home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / libs / phigs / ptk.lha / ptk / source / library / view.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-10-01  |  93.8 KB  |  3,044 lines

  1. /*----------------------------------------------------------------------------
  2.  
  3.   Module name: PHIGS View Utility.
  4.  
  5.   Author: Gareth Williams.
  6.  
  7.   Function: This module contains the PHIGS viewing utility.
  8.  
  9.   Dependencies:
  10.  
  11.   Internal function list: 
  12.  
  13.   External function list: 
  14.  
  15.   Modification history: (Version), (Date), (name), (Description).
  16.  
  17.   1.0, 26th November 1991, G. Williams, First version, based on notes by
  18.   Karen Wyrwas.
  19.  
  20.   2.0, June 1992, G. Williams, Converted to ISO PHIGS C.
  21.  
  22. ----------------------------------------------------------------------------*/
  23.  
  24. #include <stdio.h>
  25. #include <math.h>
  26. #include <phigs.h>
  27. #include "ptk.h"
  28.  
  29. #define LOCDEV 1
  30.  
  31. /*--------------------------------------------------------------------------*/
  32.  
  33. static Pint wcwindow, vrcwindow, npcwindow, dcwindow, terminalwindow;
  34. static Pint viewwsid;
  35. static Pint viewmenuid, orimenuid, mapmenuid, windowmenuid, clipmenuid;
  36. static Pint rot3d1, rot3d2, rot2d1, rot2d2, rot1d;
  37. static Ppoint rot3d1pos, rot3d2pos, rot2d1pos, rot2d2pos, rot1dpos;
  38. static Pfloat maxdevx, maxdevy;
  39. static Pint viewscene, wcscene, vrcscene, npcscene, dcscene;
  40. static Pint wcaxes, vrcaxes, npccube, projviewport, viewvolume, prpmarker;
  41. static Pint viewplane;
  42. static Ppoint3 vrp;
  43. static Ppoint3 vpn, vup;
  44. static Pview_map3 viewmap;
  45. static Pclip_ind clipxy = PIND_NO_CLIP;
  46. static Pclip_ind clipfront = PIND_NO_CLIP;
  47. static Pclip_ind clipback = PIND_NO_CLIP;
  48. static Plimit3 scenespace;
  49. static Ppoint3 initvrp, minscene, maxscene, scenevol;
  50. static Plimit echoarea;
  51. static Pmatrix3 vommat, vmmmat;
  52. static Ppoint3 origin = {0.0, 0.0, 0.0};
  53. static Pfloat axeslength;
  54. static Pfloat movefactor;
  55. static Pint curmenu = 0;
  56. static Pint curwindow = 0;
  57. static ptkboolean inputmode = TRUE;
  58. static ptkboolean dcopen = TRUE;
  59.  
  60. /* view editor attributes */
  61. static Pint menucolourind = 0;
  62. static Pint windowcolourind = 0;
  63. static Pint menutextcolourind = 1;
  64. static Pint bannercolourind = 1;
  65. static Pint bannertextcolourind = 0;
  66. static Pint menutextfont = 1;
  67. static Pint windowtextfont = 1;
  68. static Pint backgroundcolourind = 0;
  69. static Pint tlcolourind = 1;
  70. static Pint brcolourind = 1;
  71. static Pint arrowcolourind = 0;
  72. static Pint arrowedgecolourind = 1;
  73.  
  74. /*--------------------------------------------------------------------------*/
  75.  
  76. static void ptk_transformlimits3(C(Plimit3 *) lims, C(Pmatrix3) mat)
  77. PreANSI(Plimit3 *lims)
  78. PreANSI(Pmatrix3 mat)
  79. {
  80.   Ppoint3 minbox, maxbox;
  81.  
  82.   minbox = ptk_point3(lims->x_min, lims->y_min, lims->z_min);
  83.   maxbox = ptk_point3(lims->x_max, lims->y_max, lims->z_max);
  84.   minbox = ptk_transform3(mat, &minbox);
  85.   maxbox = ptk_transform3(mat, &maxbox);
  86.   *lims = ptk_limit3(minbox.x, maxbox.x, minbox.y, maxbox.y, minbox.z, 
  87.                      maxbox.z);
  88. }  /* ptk_transformlimits3 */
  89.  
  90. /*--------------------------------------------------------------------------*/
  91.  
  92. static void ptk_transformlimits(C(Plimit *) lims, C(Pmatrix) mat)
  93. PreANSI(Plimit *lims)
  94. PreANSI(Pmatrix mat)
  95. {
  96.   Ppoint minbox, maxbox;
  97.  
  98.   minbox = ptk_point(lims->x_min, lims->y_min);
  99.   maxbox = ptk_point(lims->x_max, lims->y_max);
  100.   minbox = ptk_transform(mat, &minbox);
  101.   maxbox = ptk_transform(mat, &maxbox);
  102.   *lims = ptk_limit(minbox.x, maxbox.x, minbox.y, maxbox.y);
  103. }  /* ptk_transformlimits */
  104.  
  105. /*--------------------------------------------------------------------------*/
  106.  
  107. static void ptk_shiftlimits3(C(Ppoint3 *) shift, C(Plimit3 *) lims)
  108. PreANSI(Ppoint3 *shift)
  109. PreANSI(Plimit3 *lims)
  110. {
  111.   Ppoint3 minbox, maxbox;
  112.   Pmatrix3 mat;
  113.  
  114.   minbox = ptk_point3(lims->x_min, lims->y_min, lims->z_min);
  115.   maxbox = ptk_point3(lims->x_max, lims->y_max, lims->z_max);
  116.   ptk_shift3(shift, PTYPE_REPLACE, mat);
  117.   minbox = ptk_transform3(mat, &minbox);
  118.   maxbox = ptk_transform3(mat, &maxbox);
  119.   *lims = ptk_limit3(minbox.x, maxbox.x, minbox.y, maxbox.y, minbox.z, 
  120.                      maxbox.z);
  121. }  /* ptk_shiftlimits3 */
  122.  
  123. /*--------------------------------------------------------------------------*/
  124.  
  125. static void ptk_scalelimits3(C(Ppoint3 *) scale, C(Plimit3 *) lims)
  126. PreANSI(Ppoint3 *scale)
  127. PreANSI(Plimit3 *lims)
  128. {
  129.   Ppoint3 minbox, maxbox;
  130.   Ppoint3 shift, size;
  131.   Pmatrix3 mat;
  132.  
  133.   minbox = ptk_point3(lims->x_min, lims->y_min, lims->z_min);
  134.   maxbox = ptk_point3(lims->x_max, lims->y_max, lims->z_max);
  135.   size = ptk_subv3(&maxbox, &minbox);
  136.   shift = ptk_point3(minbox.x + (size.x / 2.0), minbox.y + (size.y / 2.0),
  137.                       minbox.z + (size.z / 2.0));
  138.   shift = ptk_scalev3(&shift, -1.0);
  139.   ptk_shift3(&shift, PTYPE_REPLACE, mat);
  140.   ptk_scale3(scale, PTYPE_POSTCONCAT, mat);
  141.   shift = ptk_scalev3(&shift, -1.0);
  142.   ptk_shift3(&shift, PTYPE_POSTCONCAT, mat);
  143.   ptk_transformlimits3(lims, mat);
  144. }  /* ptk_scalelimits3 */
  145.  
  146. /*--------------------------------------------------------------------------*/
  147.  
  148. static void ptk_scalelimits(C(Ppoint *) scale, C(Plimit *) lims)
  149. PreANSI(Ppoint *scale)
  150. PreANSI(Plimit *lims)
  151. {
  152.   Ppoint minbox, maxbox;
  153.   Ppoint shift, size;
  154.   Pmatrix mat;
  155.  
  156.   minbox = ptk_point(lims->x_min, lims->y_min);
  157.   maxbox = ptk_point(lims->x_max, lims->y_max);
  158.   size = ptk_subv(&maxbox, &minbox);
  159.   shift = ptk_point(minbox.x + (size.x / 2.0), minbox.y + (size.y / 2.0));
  160.   shift = ptk_scalev(&shift, -1.0);
  161.   ptk_shift(&shift, PTYPE_REPLACE, mat);
  162.   ptk_scale(scale, PTYPE_POSTCONCAT, mat);
  163.   shift = ptk_scalev(&shift, -1.0);
  164.   ptk_shift(&shift, PTYPE_POSTCONCAT, mat);
  165.   ptk_transformlimits(lims, mat);
  166. }  /* ptk_scalelimits */
  167.  
  168. /*--------------------------------------------------------------------------*/
  169.  
  170. static void ptk_shiftlimits(C(Ppoint *) shift, C(Plimit *) lims)
  171. PreANSI(Ppoint *shift)
  172. PreANSI(Plimit *lims)
  173. {
  174.   Ppoint minbox, maxbox;
  175.   Pmatrix mat;
  176.  
  177.   minbox = ptk_point(lims->x_min, lims->y_min);
  178.   maxbox = ptk_point(lims->x_max, lims->y_max);
  179.   ptk_shift(shift, PTYPE_REPLACE, mat);
  180.   minbox = ptk_transform(mat, &minbox);
  181.   maxbox = ptk_transform(mat, &maxbox);
  182.   *lims = ptk_limit(minbox.x, maxbox.x, minbox.y, maxbox.y);
  183. }  /* ptk_shiftlimits */
  184.  
  185. /*--------------------------------------------------------------------------*/
  186.  
  187. static void do_moverotator(C(Pint) menuid)
  188. PreANSI(Pint menuid)
  189. {
  190.   Ppoint *pos, inpos;
  191.   Pint initview, view_index, tot, err;
  192.   Pin_status status;
  193.   Plimit echo;
  194.   Ploc_data locrec;
  195.   char title[30];
  196.  
  197.   pset_disp_upd_st(viewwsid, PDEFER_WAIT, PMODE_UQUM); 
  198.   ptk_inqrotatortitle(menuid, 30, title, &tot, &err);
  199.   ptk_setrotatortitle(menuid, "MOVE");
  200.   ptk_redrawallstructs(viewwsid, PFLAG_ALWAYS);
  201.   if (menuid == rot3d1)
  202.     pos = &rot3d1pos;
  203.   else
  204.   if (menuid == rot3d2)
  205.     pos = &rot3d2pos;
  206.   else
  207.   if (menuid == rot2d1)
  208.     pos = &rot2d1pos;
  209.   else
  210.   if (menuid == rot2d2)
  211.     pos = &rot2d2pos;
  212.   else
  213.   if (menuid == rot1d)
  214.     pos = &rot1dpos;
  215.   initview = 0;
  216.   echo = ptk_limit(0.0, maxdevx, 0.0, maxdevy);
  217.   /* Implementation dependent - locator data record */
  218. #ifdef HP
  219.   locrec.pets.pet_r1.loc_colr_ind = 1;
  220. #endif
  221.   pinit_loc(viewwsid, LOCDEV, initview, pos, 1, &echo, &locrec);
  222.   pset_loc_mode(viewwsid, LOCDEV, POP_REQ, PSWITCH_ECHO);
  223.   preq_loc(viewwsid, LOCDEV, &status, &view_index, &inpos);
  224.   if (status == PIN_STATUS_OK)
  225.   {
  226.     *pos = inpos;
  227.     ptk_setmenuposition(menuid, pos);
  228.   }
  229.   ptk_setrotatortitle(menuid, title);
  230. }  /* do_moverotator */
  231.  
  232. /*--------------------------------------------------------------------------*/
  233.  
  234. static void drawaxes()
  235. {
  236.   Ppoint3 pts[2];
  237.   Ppoint_list3 ptlist;
  238.  
  239.   ptlist.num_points = 2;
  240.   ptlist.points = pts;
  241.   pts[0] = ptk_point3(0.0, 0.0, 0.0);
  242.   pts[1] = ptk_point3(axeslength, 0.0, 0.0);
  243.   ppolyline3(&ptlist);
  244.   pts[1] = ptk_point3(0.0, axeslength, 0.0);
  245.   ppolyline3(&ptlist);
  246.   pts[1] = ptk_point3(0.0, 0.0, axeslength);
  247.   ppolyline3(&ptlist);
  248. }  /* drawaxes */
  249.  
  250. /*--------------------------------------------------------------------------*/
  251.  
  252. static void drawcube()
  253. {
  254.   Pint i;
  255.   Ppoint3 pts[5], lpts[2];
  256.   Ppoint_list3 ptlist;
  257.  
  258.   pts[0] = pts[4] = ptk_point3(0.0, 0.0, 0.0);
  259.   pts[1] = ptk_point3(0.0, 1.0, 0.0);
  260.   pts[2] = ptk_point3(1.0, 1.0, 0.0);
  261.   pts[3] = ptk_point3(1.0, 0.0, 0.0);
  262.   ptlist.num_points = 5;
  263.   ptlist.points = pts;
  264.   ppolyline3(&ptlist);
  265.   for (i = 0; i < 5; i++)
  266.     pts[i].z += 1.0;
  267.   ppolyline3(&ptlist);
  268.   ptlist.num_points = 2;
  269.   ptlist.points = lpts;
  270.   for (i = 0; i < 5; i++)
  271.   {
  272.     lpts[0] = lpts[1] = pts[i];
  273.     lpts[1].z -= 1.0;
  274.     ppolyline3(&ptlist);
  275.   }
  276. }  /* drawcube */
  277.  
  278. /*--------------------------------------------------------------------------*/
  279.  
  280. static void makeviewstructs()
  281. {
  282.   Pmatrix3 unitmat;
  283.   Ppoint3 refpt, offset, markerpt, pts[5];
  284.   Ppoint_list3 ptlist;
  285.  
  286.   ptk_unitmatrix3(unitmat);
  287.   wcaxes = ptk_stringtoint("structureid", "ptk$viewwcaxes");
  288.   vrcaxes = ptk_stringtoint("structureid", "ptk$viewvrcaxes");
  289.   npccube = ptk_stringtoint("structureid", "ptk$viewnpccube");
  290.   projviewport = ptk_stringtoint("structureid", "ptk$viewprojviewport");
  291.   viewvolume = ptk_stringtoint("structureid", "ptk$viewviewvolume");
  292.   prpmarker = ptk_stringtoint("structureid", "ptk$viewprpmarker");
  293.   viewplane = ptk_stringtoint("structureid", "ptk$viewviewplane");
  294.   
  295.   ptk_openstruct(wcaxes);
  296.   drawaxes();
  297.   refpt = ptk_point3(axeslength, 0.0, 0.0);
  298.   offset = ptk_point3(0.0, 0.0, 0.0);
  299.   panno_text_rel3(&refpt, &offset, "X");
  300.   refpt = ptk_point3(0.0, axeslength, 0.0);
  301.   panno_text_rel3(&refpt, &offset, "Y");
  302.   refpt = ptk_point3(0.0, 0.0, axeslength);
  303.   panno_text_rel3(&refpt, &offset, "Z");
  304.   ptk_closestruct();
  305.  
  306.   ptk_openstruct(vrcaxes);
  307.   plabel(ptk_stringtoint("label", "view$mx_inv_vom"));
  308.   pset_local_tran3(unitmat, PTYPE_REPLACE);
  309.   drawaxes();
  310.   refpt = ptk_point3(axeslength, 0.0, 0.0);
  311.   offset = ptk_point3(0.0, 0.0, 0.0);
  312.   panno_text_rel3(&refpt, &offset, "U");
  313.   refpt = ptk_point3(0.0, axeslength, 0.0);
  314.   panno_text_rel3(&refpt, &offset, "V");
  315.   refpt = ptk_point3(0.0, 0.0, axeslength);
  316.   panno_text_rel3(&refpt, &offset, "N");
  317.   ptk_closestruct();
  318.  
  319.   ptk_openstruct(npccube);
  320.   drawcube();
  321.   ptk_closestruct();
  322.  
  323.   ptk_openstruct(projviewport);
  324.   plabel(ptk_stringtoint("label", "view$mx_proj_viewport"));
  325.   pset_local_tran3(unitmat, PTYPE_REPLACE);
  326.   pset_linetype(PLINE_DASH);
  327.   drawcube();
  328.   ptk_closestruct();
  329.  
  330.   ptk_openstruct(viewvolume);
  331.   plabel(ptk_stringtoint("label", "view$mx_view_volume"));
  332.   pset_local_tran3(unitmat, PTYPE_REPLACE);
  333.   drawcube();
  334.   ptk_closestruct();
  335.  
  336.   ptk_openstruct(prpmarker);
  337.   plabel(ptk_stringtoint("label", "view$mx_prp"));
  338.   pset_local_tran3(unitmat, PTYPE_REPLACE);
  339.   markerpt = ptk_point3(0.0, 0.0, 0.0);
  340.   ptlist.num_points = 1;
  341.   ptlist.points = &markerpt;
  342.   ppolymarker3(&ptlist);
  343.   ptk_closestruct();
  344.  
  345.   ptk_openstruct(viewplane);
  346.   plabel(ptk_stringtoint("label", "view$mx_view_plane"));
  347.   pset_local_tran3(unitmat, PTYPE_REPLACE);
  348.   pts[0] = pts[4] = ptk_point3(0.0, 0.0, 0.0);
  349.   pts[1] = ptk_point3(0.0, 1.0, 0.0);
  350.   pts[2] = ptk_point3(1.0, 1.0, 0.0);
  351.   pts[3] = ptk_point3(1.0, 0.0, 0.0);
  352.   ptlist.num_points = 5;
  353.   ptlist.points = pts;
  354.   ppolyline3(&ptlist);
  355.   ptk_closestruct();  
  356. }  /* makeviewstructs */
  357.  
  358. /*--------------------------------------------------------------------------*/
  359.  
  360. static void combinelimits(C(Plimit3 *) lim1, C(Plimit3 *) lim2)
  361. PreANSI(Plimit3 *lim1)
  362. PreANSI(Plimit3 *lim2)
  363. {
  364.   if (lim1->x_min < lim2->x_min)
  365.     lim2->x_min = lim1->x_min;
  366.   if (lim1->x_max > lim2->x_max)
  367.     lim2->x_max = lim1->x_max;
  368.   if (lim1->y_min < lim2->y_min)
  369.     lim2->y_min = lim1->y_min;
  370.   if (lim1->y_max > lim2->y_max)
  371.     lim2->y_max = lim1->y_max;
  372.   if (lim1->z_min < lim2->z_min)
  373.     lim2->z_min = lim1->z_min;
  374.   if (lim1->z_max > lim2->z_max)
  375.     lim2->z_max = lim1->z_max;
  376. }  /* combinelimits */
  377.  
  378. /*--------------------------------------------------------------------------*/
  379.  
  380. static ptkboolean do_scene(C(Pint_list *) stids)
  381. PreANSI(Pint_list *stids)
  382. {
  383.   Plimit3 stlimits;
  384.   Ppoint3 minbox, maxbox, dimen;
  385.   Pint i;
  386.  
  387.   scenespace = ptk_limit3(10000.0, -10000.0, 10000.0, -10000.0, 
  388.                           10000.0, -10000.0);
  389.   for (i = 0; i < stids->num_ints; i++)
  390.   {
  391.     if (ptk_boundingbox(stids->ints[i], &stlimits, TRUE))
  392.     {
  393.       if (stlimits.x_min < scenespace.x_min)
  394.         scenespace.x_min = stlimits.x_min;
  395.       if (stlimits.y_min < scenespace.y_min)
  396.         scenespace.y_min = stlimits.y_min;
  397.       if (stlimits.z_min < scenespace.z_min)
  398.         scenespace.z_min = stlimits.z_min;
  399.       if (stlimits.x_max > scenespace.x_max)
  400.         scenespace.x_max = stlimits.x_max;
  401.       if (stlimits.y_max > scenespace.y_max)
  402.         scenespace.y_max = stlimits.y_max;
  403.       if (stlimits.z_max > scenespace.z_max)
  404.         scenespace.z_max = stlimits.z_max;
  405.     }
  406.   }
  407.   if (scenespace.x_min == 10000.0)
  408.     return FALSE;
  409.   minbox = ptk_point3(scenespace.x_min, scenespace.y_min, scenespace.z_min);
  410.   maxbox = ptk_point3(scenespace.x_max, scenespace.y_max, scenespace.z_max);
  411.   dimen = ptk_subv3(&maxbox, &minbox);
  412.   axeslength = PTKMAX(dimen.x, dimen.y);
  413.   axeslength = PTKMAX(axeslength, dimen.z);
  414.   movefactor = axeslength / 10.0;
  415.   axeslength /= 2.0;
  416.   pempty_struct(viewscene);
  417.   ptk_openstruct(viewscene);
  418.   for (i = 0; i < stids->num_ints; i++)
  419.     pexec_struct(stids->ints[i]);
  420.   ptk_closestruct();
  421.   return TRUE;
  422. }  /* do_scene */
  423.  
  424. /*--------------------------------------------------------------------------*/
  425.  
  426. static void initialiseeditor()
  427. {
  428.   Pint i, err;
  429.   Pmatrix3 unitmat;
  430.   Plimit3 stlimits, wclimits, axeslimits;
  431.   Pint_list windworld;
  432.   Pfloat maxscenevol;
  433.  
  434.   /* view settings */
  435.   vpn = ptk_point3(0.0, 0.0, 1.0);
  436.   vup = ptk_point3(0.0, 1.0, 0.0);
  437.   viewmap.view_plane = 0.0;
  438.   viewmap.proj_type = PTYPE_PARAL;
  439.  
  440.   /* find centre of scene */
  441.   minscene = ptk_point3(scenespace.x_min, scenespace.y_min, scenespace.z_min);
  442.   maxscene = ptk_point3(scenespace.x_max, scenespace.y_max, scenespace.z_max);
  443.   initvrp = ptk_subv3(&maxscene, &minscene);
  444.   initvrp = ptk_scalev3(&initvrp, 0.5);
  445.   initvrp = ptk_addv3(&initvrp, &minscene);
  446.   vrp = initvrp;
  447.   scenevol = ptk_subv3(&maxscene, &minscene);
  448.   maxscenevol = PTKMAX(scenevol.x, scenevol.y);
  449.   maxscenevol = PTKMAX(maxscenevol, scenevol.z);
  450.   maxscenevol *= 2.0;
  451.   viewmap.win = ptk_limit(-scenevol.x / 2.0, scenevol.x / 2.0, 
  452.                              -scenevol.y / 2.0, scenevol.y / 2.0);
  453.   viewmap.proj_ref_point = ptk_point3(0.0, 0.0, maxscenevol / 2.0);
  454.   viewmap.front_plane = scenevol.z + (maxscenevol / 20.0);
  455.   viewmap.back_plane = -viewmap.front_plane;
  456.  
  457.   viewmap.proj_vp = ptk_limit3(0.5 - scenevol.x / maxscenevol, 
  458.                              0.5 + scenevol.x / maxscenevol,
  459.                              0.5 - scenevol.y / maxscenevol, 
  460.                              0.5 + scenevol.y / maxscenevol,
  461.                              0.5 - scenevol.z / maxscenevol, 
  462.                              0.5 + scenevol.z / maxscenevol);
  463.   ptk_unitmatrix3(unitmat);
  464.   ptk_unitmatrix3(vommat);
  465.   ptk_unitmatrix3(vmmmat);
  466.  
  467.   ptk_openstruct(wcscene);
  468.   pexec_struct(viewscene);
  469.   pexec_struct(wcaxes);
  470.   pexec_struct(vrcaxes);
  471.   ptk_closestruct();
  472.  
  473.   ptk_openstruct(vrcscene);
  474.   plabel(ptk_stringtoint("label", "view$mx_vom"));
  475.   pset_local_tran3(unitmat, PTYPE_REPLACE);
  476.   pexec_struct(viewscene);
  477.   pexec_struct(viewvolume);
  478.   pexec_struct(viewplane);
  479.   plabel(ptk_stringtoint("label", "view$mx_vrp"));
  480.   pset_local_tran3(unitmat, PTYPE_POSTCONCAT);
  481.   pexec_struct(prpmarker);
  482.   ptk_closestruct();
  483.  
  484.   ptk_openstruct(npcscene);
  485.   plabel(ptk_stringtoint("label", "view$mx_vom"));
  486.   pset_local_tran3(unitmat, PTYPE_REPLACE);
  487.   plabel(ptk_stringtoint("label", "view$mx_vmm"));
  488.   pset_local_tran3(unitmat, PTYPE_POSTCONCAT);
  489.   pexec_struct(viewscene);
  490.   pset_local_tran3(unitmat, PTYPE_REPLACE);
  491.   pexec_struct(npccube);
  492.   pexec_struct(projviewport);
  493.   ptk_closestruct();
  494.  
  495.   ptk_openstruct(dcscene);
  496.   plabel(ptk_stringtoint("label", "view$mx_vom"));
  497.   pset_local_tran3(unitmat, PTYPE_REPLACE);
  498.   plabel(ptk_stringtoint("label", "view$mx_vmm"));
  499.   pset_local_tran3(unitmat, PTYPE_POSTCONCAT);
  500.   pexec_struct(viewscene);
  501.   ptk_closestruct();
  502.  
  503.   wclimits = scenespace;
  504.   ptk_boundingbox(wcaxes, &axeslimits, TRUE);
  505.   combinelimits(&axeslimits, &wclimits);
  506.   ptk_boundingbox(vrcaxes, &axeslimits, TRUE);
  507.   combinelimits(&axeslimits, &wclimits);
  508.   
  509. /*  wclimits.x_max = MAX(fabs(scenespace.x_min), fabs(scenespace.x_max));
  510.   wclimits.y_max = MAX(fabs(scenespace.y_min), fabs(scenespace.y_max));
  511.   wclimits.z_max = MAX(fabs(scenespace.z_min), fabs(scenespace.z_max));
  512.   wclimits.x_min = -wclimits.x_max; 
  513.   wclimits.y_min = -wclimits.y_max; 
  514.   wclimits.z_min = -wclimits.z_max;  */
  515.  
  516.   ptk_setcameralimits(wcwindow, &wclimits, TRUE);
  517.   ptk_setcamerastate(dcwindow, PTKECAMERAOFF);
  518.   ptk_posttowindow(wcwindow, wcscene);   
  519.   ptk_posttowindow(vrcwindow, vrcscene);
  520.   ptk_posttowindow(npcwindow, npcscene);
  521.   ptk_posttowindow(dcwindow, dcscene);
  522. }  /* initialiseeditor */
  523.  
  524. /*--------------------------------------------------------------------------*/
  525.  
  526. static ptkboolean checkmapping(C(Pview_map3 *) map)
  527. PreANSI(Pview_map3 *map)
  528. {
  529.   Pint err;
  530.   Pmatrix3 mat;
  531.  
  532.   peval_view_map_matrix3(map, &err, mat);
  533.   if (err == 0)
  534.     return TRUE;
  535.   else
  536.     return FALSE;
  537. }  /* checkmapping */
  538.  
  539. /*--------------------------------------------------------------------------*/
  540.  
  541. static void updatevrcwindow()
  542. {
  543.   Plimit3 limits, templims;
  544.  
  545.   limits = scenespace;
  546.   ptk_boundingbox(viewvolume, &templims, TRUE);
  547.   combinelimits(&templims, &limits);
  548.   ptk_boundingbox(prpmarker, &templims, TRUE);
  549.   combinelimits(&templims, &limits);
  550.   ptk_transformlimits3(&limits, vommat);
  551.   ptk_setcameralimits(vrcwindow, &limits, TRUE);
  552. }  /* updatevrcwindow */
  553.  
  554. /*--------------------------------------------------------------------------*/
  555.  
  556. static void updatenpcwindow()
  557. {
  558.   Plimit3 limits, templims;
  559.   Pmatrix3 mat;
  560.  
  561.   limits = scenespace;
  562.   ptk_multiplymatrix3(vmmmat, vommat, mat);
  563.   ptk_transformlimits3(&limits, mat);
  564.   templims = ptk_limit3(0.0, 1.0, 0.0, 1.0, 0.0, 1.0);
  565.   combinelimits(&templims, &limits);
  566.   ptk_setcameralimits(npcwindow, &limits, TRUE);
  567. }  /* updatenpcwindow */
  568.  
  569. /*--------------------------------------------------------------------------*/
  570.  
  571. static void updatedcwindow()
  572. {
  573.   Pint err;
  574.   Plimit window;
  575.   Ppoint3 prp, vrp;
  576.   Pfloat width, height, depth;
  577.   Ppoint3 vpn, vup;
  578.  
  579.   width = viewmap.proj_vp.x_max - viewmap.proj_vp.x_min;
  580.   height = viewmap.proj_vp.y_max - viewmap.proj_vp.y_min;
  581.   depth = viewmap.proj_vp.z_max - viewmap.proj_vp.z_min;
  582.   vpn = ptk_point3(0.0, 0.0, 1.0);
  583.   vup = ptk_point3(0.0, 1.0, 0.0);
  584.   vrp = ptk_point3(width / 2.0 + viewmap.proj_vp.x_min,
  585.                    height / 2.0 + viewmap.proj_vp.y_min,
  586.                    depth / 2.0 + viewmap.proj_vp.z_min);
  587.   ptk_setvieworientation3(dcwindow, &vrp, &vpn, &vup, &err);
  588.   window = ptk_limit(-width / 2.0, width / 2.0, -height / 2.0, height / 2.0);
  589.   prp = ptk_point3(0.0, 0.0, 2.0);
  590.   ptk_setviewmapping3(dcwindow, &window, &viewmap.proj_vp, PTYPE_PARAL,
  591.                       &prp, 0.0, -depth / 2.0, depth / 2.0, &err); 
  592.   ptk_setviewclipping3(dcwindow, &viewmap.proj_vp, clipxy, clipback, 
  593.                        clipfront);
  594. }  /* updatedcwindow */
  595.  
  596. /*--------------------------------------------------------------------------*/
  597.  
  598. static void updatewindows()
  599. {
  600.   updatevrcwindow();
  601.   updatenpcwindow();
  602.   updatedcwindow();
  603. }  /* updatewindows */ 
  604.  
  605. /*--------------------------------------------------------------------------*/
  606.  
  607. static void updatemxvom()
  608. {
  609.   Pint err;
  610.   Pmatrix3 vrpmat;
  611.  
  612.   /* view orientation matrix */
  613.   ptk_pevalvieworientationmatrix3(&vrp, &vpn, &vup, &err, vommat);
  614.   /* edit all structures using vom */
  615.   ptk_seteditmode(PEDIT_REPLACE);
  616.   ptk_openstruct(vrcscene);
  617.   pset_elem_ptr(0);
  618.   pset_elem_ptr_label(ptk_stringtoint("label", "view$mx_vom"));
  619.   poffset_elem_ptr(1);
  620.   pset_local_tran3(vommat, PTYPE_REPLACE);
  621.   pset_elem_ptr_label(ptk_stringtoint("label", "view$mx_vrp"));
  622.   poffset_elem_ptr(1);
  623.   ptk_shift3(&vrp, PTYPE_REPLACE, vrpmat);
  624.   pset_local_tran3(vrpmat, PTYPE_PRECONCAT);
  625.   ptk_closestruct();
  626.  
  627.   ptk_openstruct(npcscene);
  628.   pset_elem_ptr(0);
  629.   pset_elem_ptr_label(ptk_stringtoint("label", "view$mx_vom"));
  630.   poffset_elem_ptr(1);
  631.   pset_local_tran3(vommat, PTYPE_REPLACE);
  632.   ptk_closestruct();
  633.  
  634.   ptk_openstruct(dcscene);
  635.   pset_elem_ptr(0);
  636.   pset_elem_ptr_label(ptk_stringtoint("label", "view$mx_vom"));
  637.   poffset_elem_ptr(1);
  638.   pset_local_tran3(vommat, PTYPE_REPLACE);
  639.   ptk_closestruct();
  640.   ptk_unseteditmode();
  641. }  /* updatemxvom */
  642.  
  643. /*--------------------------------------------------------------------------*/
  644.  
  645. static void updatemxinvvom()
  646. {
  647.   Pmatrix3 invvommat;
  648.   Pint err;
  649.   
  650.   ptk_invertmatrix3(vommat, invvommat, &err);
  651.   /* edit all structures using invvom */
  652.   ptk_seteditmode(PEDIT_REPLACE);
  653.   ptk_openstruct(vrcaxes);
  654.   pset_elem_ptr(0);
  655.   pset_elem_ptr_label(ptk_stringtoint("label", "view$mx_inv_vom"));
  656.   poffset_elem_ptr(1);
  657.   pset_local_tran3(invvommat, PTYPE_REPLACE);
  658.   ptk_closestruct();
  659.   ptk_unseteditmode();
  660. }  /* updatemxinvvom */
  661.  
  662. /*--------------------------------------------------------------------------*/
  663.  
  664. static void updatemxvmm()
  665. {
  666.   Pint err;
  667.  
  668.   /* view mapping matrix */
  669.   peval_view_map_matrix3(&viewmap, &err, vmmmat);
  670.  
  671.   ptk_seteditmode(PEDIT_REPLACE);
  672.   ptk_openstruct(npcscene);
  673.   pset_elem_ptr(0);
  674.   pset_elem_ptr_label(ptk_stringtoint("label", "view$mx_vmm"));
  675.   poffset_elem_ptr(1);
  676.   pset_local_tran3(vmmmat, PTYPE_POSTCONCAT);
  677.   ptk_closestruct();
  678.  
  679.   ptk_openstruct(dcscene);
  680.   pset_elem_ptr(0);
  681.   pset_elem_ptr_label(ptk_stringtoint("label", "view$mx_vmm"));
  682.   poffset_elem_ptr(1);
  683.   pset_local_tran3(vmmmat, PTYPE_POSTCONCAT);
  684.   ptk_closestruct();
  685.   ptk_unseteditmode();  
  686. }  /* updatemxvmm */
  687.  
  688. /*--------------------------------------------------------------------------*/
  689.  
  690. static void updatemxviewvolume()
  691. {
  692.   Plimit3 unitcube, viewvol;
  693.   Pmatrix3 viewvolmat;
  694.   Pint err;
  695.  
  696.   unitcube = ptk_limit3(0.0, 1.0, 0.0, 1.0, 0.0, 1.0);
  697.   viewvol = ptk_limit3(viewmap.win.x_min, viewmap.win.x_max,
  698.                        viewmap.win.y_min, viewmap.win.y_max, 
  699.                        viewmap.back_plane, viewmap.front_plane);
  700.   viewvol.x_min += vrp.x;
  701.   viewvol.x_max += vrp.x;
  702.   viewvol.y_min += vrp.y;
  703.   viewvol.y_max += vrp.y;
  704.   viewvol.z_min += vrp.z;
  705.   viewvol.z_max += vrp.z;
  706.   ptk_box3tobox3(&unitcube, &viewvol, FALSE, PTYPE_REPLACE, viewvolmat, &err);
  707.   ptk_seteditmode(PEDIT_REPLACE);
  708.   ptk_openstruct(viewvolume);
  709.   pset_elem_ptr(0);
  710.   pset_elem_ptr_label(ptk_stringtoint("label", "view$mx_view_volume"));
  711.   poffset_elem_ptr(1);
  712.   pset_local_tran3(viewvolmat, PTYPE_REPLACE);
  713.   ptk_closestruct();
  714.   ptk_unseteditmode();
  715. }  /* updatemxviewvolume */
  716.  
  717. /*--------------------------------------------------------------------------*/
  718.  
  719. static void updatemxprojviewport()
  720. {
  721.   Plimit3 unitcube, viewvol;
  722.   Pmatrix3 projviewmat;
  723.   Pint err;
  724.  
  725.   unitcube = ptk_limit3(0.0, 1.0, 0.0, 1.0, 0.0, 1.0);
  726.   ptk_box3tobox3(&unitcube, &viewmap.proj_vp, FALSE, PTYPE_REPLACE, projviewmat,
  727.                  &err);
  728.   ptk_seteditmode(PEDIT_REPLACE);
  729.   ptk_openstruct(projviewport);
  730.   pset_elem_ptr(0);
  731.   pset_elem_ptr_label(ptk_stringtoint("label", "view$mx_proj_viewport"));
  732.   poffset_elem_ptr(1);
  733.   pset_local_tran3(projviewmat, PTYPE_REPLACE);
  734.   ptk_closestruct();
  735.   ptk_unseteditmode();
  736. }  /* updatemxprojviewport */
  737.  
  738. /*--------------------------------------------------------------------------*/
  739.  
  740. static void updatemxprp()
  741. {
  742.   Pmatrix3 prpmat;
  743.   Ppoint3 shiftprp;
  744.   Pint err;
  745.  
  746. /*  shiftprp = ptk_scalev3(&viewmap.proj_ref_point, -1.0); */
  747.   shiftprp = viewmap.proj_ref_point;
  748.   ptk_shift3(&shiftprp, PTYPE_REPLACE, prpmat);
  749.   ptk_seteditmode(PEDIT_REPLACE);
  750.   ptk_openstruct(prpmarker);
  751.   pset_elem_ptr(0);
  752.   pset_elem_ptr_label(ptk_stringtoint("label", "view$mx_prp"));
  753.   poffset_elem_ptr(1);
  754.   pset_local_tran3(prpmat, PTYPE_REPLACE);
  755.   ptk_closestruct();
  756.   ptk_unseteditmode();
  757. }  /* updatemxprp */
  758.  
  759. /*--------------------------------------------------------------------------*/
  760.  
  761. static void updatemxviewplane()
  762. {
  763.   Pmatrix3 viewplanemat;
  764.   Plimit3 unitcube, viewvol;
  765.   Pint err;
  766.  
  767.   unitcube = ptk_limit3(0.0, 1.0, 0.0, 1.0, 0.0, 0.0);
  768.   viewvol = ptk_limit3(viewmap.win.x_min, viewmap.win.x_max,
  769.                        viewmap.win.y_min, viewmap.win.y_max, 
  770.                        viewmap.view_plane, viewmap.view_plane);
  771.   viewvol.x_min += vrp.x;
  772.   viewvol.x_max += vrp.x;
  773.   viewvol.y_min += vrp.y;
  774.   viewvol.y_max += vrp.y;
  775.   viewvol.z_min += vrp.z;
  776.   viewvol.z_max += vrp.z; 
  777.   ptk_box3tobox3(&unitcube, &viewvol, FALSE, PTYPE_REPLACE, viewplanemat, &err);
  778.   ptk_seteditmode(PEDIT_REPLACE);
  779.   ptk_openstruct(viewplane);
  780.   pset_elem_ptr(0);
  781.   pset_elem_ptr_label(ptk_stringtoint("label", "view$mx_view_plane"));
  782.   poffset_elem_ptr(1);
  783.   pset_local_tran3(viewplanemat, PTYPE_REPLACE);
  784.   ptk_closestruct();
  785.   ptk_unseteditmode();
  786. }  /* updatemxviewplane */
  787.  
  788. /*--------------------------------------------------------------------------*/
  789.  
  790. static void do_shiftpoint3(C(ptksmenuoutput *) menuout, C(Ppoint3 *) pt)
  791. PreANSI(ptksmenuoutput *menuout)
  792. PreANSI(Ppoint3 *pt)
  793. {
  794.   Ppoint shift;
  795.   Pfloat shiftfactor;
  796.  
  797.   switch (menuout->itemnum)
  798.   {
  799.     case 1: /* increase y */
  800.       shiftfactor = menuout->value.y * movefactor;
  801.       pt->y += shiftfactor;
  802.       break;
  803.  
  804.     case 2: /* decrease y */
  805.       shiftfactor = (1.0 - menuout->value.y) * movefactor;
  806.       pt->y -= shiftfactor;
  807.       break;
  808.  
  809.     case 3: /* decrease x */
  810.       shiftfactor = (1.0 - menuout->value.x) * movefactor;
  811.       pt->x -= shiftfactor;
  812.       break;
  813.  
  814.     case 4: /* increase x */
  815.       shiftfactor = menuout->value.x * movefactor;
  816.       pt->x += shiftfactor;
  817.       break;
  818.  
  819.     case 5: /* decrease z */
  820.       shiftfactor = menuout->value.y * movefactor;
  821.       pt->z -= shiftfactor;
  822.       break;
  823.  
  824.     case 6: /* increase z */
  825.       shiftfactor = menuout->value.y * movefactor;
  826.       pt->z += shiftfactor;
  827.       break;
  828.   }
  829. }  /* do_shiftpoint3 */
  830.  
  831. /*--------------------------------------------------------------------------*/
  832.  
  833. static void do_vrp()
  834. {
  835.   Ppoint locpos;
  836.   ptkboolean quit;
  837.   Pint wsid, devnum, viewindex;
  838.   Pin_class class;
  839.   ptksgeneralinput geninput;
  840.   ptksmenuoutput menuoutput;
  841.  
  842.   if (dcopen)
  843.     pset_disp_upd_st(viewwsid, PDEFER_WAIT, PMODE_NIVE); 
  844.   if (!inputmode)
  845.   {
  846.     vrp.x = ptk_readfloat(viewwsid, 0.0, "Input vrp, x (0.0) >", &echoarea);
  847.     vrp.y = ptk_readfloat(viewwsid, 0.0, "Input vrp, y (0.0) >", &echoarea);
  848.     vrp.z = ptk_readfloat(viewwsid, 0.0, "Input vrp, z (0.0) >", &echoarea);
  849.     updatemxvom();
  850.     updatemxinvvom();
  851.     updatemxviewvolume();
  852.     updatemxviewplane();
  853.     updatemxprp();
  854.     updatedcwindow();
  855.     ptk_redrawallstructs(viewwsid, PFLAG_ALWAYS);
  856.   }
  857.   else
  858.   {
  859.     ptk_setrotatortitle(rot3d1, "shift vrp");
  860.     ptk_postmenu(viewwsid, rot3d1);
  861.     ptk_redrawallstructs(viewwsid, PFLAG_ALWAYS);
  862.     pset_loc_mode(viewwsid, LOCDEV, POP_EVENT, PSWITCH_ECHO);
  863.     quit = FALSE;
  864.     do
  865.     {
  866.       if (dcopen)
  867.         pset_disp_upd_st(viewwsid, PDEFER_WAIT, PMODE_NIVE); 
  868.       pawait_event(0.0, &wsid, &class, &devnum);
  869.       if ((class == PIN_LOC) && (wsid == viewwsid))
  870.       {
  871.         pget_loc(&viewindex, &locpos);
  872.         geninput.inputclass = PIN_LOC;
  873.         geninput.ptkugeninput.locpoint = locpos;
  874.         if (ptk_scanmenus(viewwsid, &geninput, &menuoutput))
  875.         {
  876.           pset_loc_mode(viewwsid, LOCDEV, POP_REQ, PSWITCH_ECHO);
  877.           if (menuoutput.menuid == rot3d1)
  878.       {
  879.             if (menuoutput.itemnum == 0)
  880.               do_moverotator(rot3d1);
  881.             else
  882.         {
  883.               do_shiftpoint3(&menuoutput, &vrp);
  884.               updatemxvom();
  885.               updatemxinvvom();
  886.               updatemxviewvolume();
  887.               updatemxviewplane();
  888.               updatemxprp();
  889.               updatedcwindow();
  890.             }
  891.             ptk_redrawallstructs(viewwsid, PFLAG_ALWAYS);
  892.       }
  893.           pset_loc_mode(viewwsid, LOCDEV, POP_EVENT, PSWITCH_ECHO);
  894.         }
  895.         else
  896.         {
  897.           quit = TRUE;
  898.         }
  899.       }
  900.     } while (!quit);
  901.   }
  902.   ptk_unpostmenu(viewwsid, rot3d1);
  903. } /* do_vrp */
  904.  
  905. /*--------------------------------------------------------------------------*/
  906.  
  907. static void do_rotatevector(C(ptksmenuoutput *) menuout, C(Ppoint3 *) vec)
  908. PreANSI(ptksmenuoutput *menuout)
  909. PreANSI(Ppoint3 *vec)
  910. {
  911.   Ppoint3 axis;
  912.   Pmatrix3 mat;
  913.   Pint err;
  914.   Pfloat angle;
  915.  
  916.   switch (menuout->itemnum)
  917.   {
  918.     case 1:
  919.       angle = menuout->value.y * 10.0;
  920.       axis = ptk_point3(1.0, 0.0, 0.0);
  921.       ptk_rotateline3(&origin, &axis, -angle, PTYPE_REPLACE, mat, &err);
  922.       *vec = ptk_transform3(mat, vec);
  923.       break;
  924.  
  925.     case 2:
  926.       angle = (1.0 - menuout->value.y) * 10.0;
  927.       axis = ptk_point3(1.0, 0.0, 0.0);
  928.       ptk_rotateline3(&origin, &axis, angle, PTYPE_REPLACE, mat, &err);
  929.       *vec = ptk_transform3(mat, vec);
  930.       break;
  931.  
  932.     case 3:
  933.       angle = (1.0 - menuout->value.y) * 10.0;
  934.       axis = ptk_point3(0.0, 1.0, 0.0);
  935.       ptk_rotateline3(&origin, &axis, -angle, PTYPE_REPLACE, mat, &err);
  936.       *vec = ptk_transform3(mat, vec);
  937.       break;
  938.  
  939.     case 4:
  940.       angle = menuout->value.y * 10.0;
  941.       axis = ptk_point3(0.0, 1.0, 0.0);
  942.       ptk_rotateline3(&origin, &axis, angle, PTYPE_REPLACE, mat, &err);
  943.       *vec = ptk_transform3(mat, vec);
  944.       break;
  945.  
  946.     case 5:
  947.       angle = menuout->value.y * 10.0;
  948.       axis = ptk_point3(0.0, 0.0, 1.0);
  949.       ptk_rotateline3(&origin, &axis, angle, PTYPE_REPLACE, mat, &err);
  950.       *vec = ptk_transform3(mat, vec);
  951.       break;
  952.  
  953.     case 6:
  954.       angle = menuout->value.y * 10.0;
  955.       axis = ptk_point3(0.0, 0.0, 1.0);
  956.       ptk_rotateline3(&origin, &axis, -angle, PTYPE_REPLACE, mat, &err);
  957.       *vec = ptk_transform3(mat, vec);
  958.       break;
  959.   }
  960. }  /* do_rotatevector */
  961.  
  962. /*--------------------------------------------------------------------------*/
  963.  
  964. static void do_vpn()
  965. {
  966.   Ppoint locpos;
  967.   ptkboolean quit;
  968.   Pint wsid, devnum, viewindex;
  969.   Pin_class class;
  970.   ptksgeneralinput geninput;
  971.   ptksmenuoutput menuoutput;
  972.  
  973.   if (dcopen)
  974.     pset_disp_upd_st(viewwsid, PDEFER_WAIT, PMODE_NIVE); 
  975.   if (!inputmode)
  976.   {
  977.     vpn.x = ptk_readfloat(viewwsid, 0.0, "Input vpn, x (0.0) >", &echoarea);
  978.     vpn.y = ptk_readfloat(viewwsid, 0.0, "Input vpn, y (0.0) >", &echoarea);
  979.     vpn.z = ptk_readfloat(viewwsid, 0.0, "Input vpn, z (0.0) >", &echoarea); 
  980.     updatemxvom();
  981.     updatemxinvvom();
  982.     updatedcwindow();
  983.     ptk_redrawallstructs(viewwsid, PFLAG_ALWAYS);
  984.   }
  985.   else
  986.   {
  987.     ptk_setrotatortitle(rot3d1, "rotate vpn");
  988.     ptk_postmenu(viewwsid, rot3d1);
  989.     ptk_redrawallstructs(viewwsid, PFLAG_ALWAYS);
  990.     pset_loc_mode(viewwsid, LOCDEV, POP_EVENT, PSWITCH_ECHO);
  991.     quit = FALSE;
  992.     do
  993.     {
  994.       if (dcopen)
  995.         pset_disp_upd_st(viewwsid, PDEFER_WAIT, PMODE_NIVE); 
  996.       pawait_event(0.0, &wsid, &class, &devnum);
  997.       if ((class == PIN_LOC) && (wsid == viewwsid))
  998.       {
  999.         pget_loc(&viewindex, &locpos);
  1000.         geninput.inputclass = PIN_LOC;
  1001.         geninput.ptkugeninput.locpoint = locpos;
  1002.         if (ptk_scanmenus(viewwsid, &geninput, &menuoutput))
  1003.         {
  1004.           pset_loc_mode(viewwsid, LOCDEV, POP_REQ, PSWITCH_ECHO);
  1005.           if (menuoutput.menuid == rot3d1)
  1006.       {
  1007.             if (menuoutput.itemnum == 0)
  1008.               do_moverotator(rot3d1);
  1009.             else
  1010.         {
  1011.               do_rotatevector(&menuoutput, &vpn);
  1012.               updatemxvom();
  1013.               updatemxinvvom();
  1014.               updatedcwindow();
  1015.             }
  1016.             ptk_redrawallstructs(viewwsid, PFLAG_ALWAYS);
  1017.       }
  1018.           pset_loc_mode(viewwsid, LOCDEV, POP_EVENT, PSWITCH_ECHO);
  1019.         }
  1020.         else
  1021.         {
  1022.           quit = TRUE;
  1023.         }
  1024.       }
  1025.     } while (!quit);
  1026.   }
  1027.   ptk_unpostmenu(viewwsid, rot3d1);
  1028. } /* do_vpn */
  1029.  
  1030. /*--------------------------------------------------------------------------*/
  1031.  
  1032. static void do_vup()
  1033. {
  1034.   Ppoint locpos;
  1035.   ptkboolean quit;
  1036.   Pint wsid, devnum, viewindex;
  1037.   Pin_class class;
  1038.   ptksgeneralinput geninput;
  1039.   ptksmenuoutput menuoutput;
  1040.  
  1041.   if (dcopen)
  1042.     pset_disp_upd_st(viewwsid, PDEFER_WAIT, PMODE_NIVE); 
  1043.   if (!inputmode)
  1044.   {
  1045.     vup.x = ptk_readfloat(viewwsid, 0.0, "Input vup, x (0.0) >", &echoarea);
  1046.     vup.y = ptk_readfloat(viewwsid, 0.0, "Input vup, y (0.0) >", &echoarea);
  1047.     vup.z = ptk_readfloat(viewwsid, 0.0, "Input vup, z (0.0) >", &echoarea);
  1048.     updatemxvom();
  1049.     updatemxinvvom();
  1050.     updatedcwindow();
  1051.     ptk_redrawallstructs(viewwsid, PFLAG_ALWAYS);
  1052.   }
  1053.   else
  1054.   {
  1055.     ptk_setrotatortitle(rot3d1, "rotate vup");
  1056.     ptk_postmenu(viewwsid, rot3d1);
  1057.     ptk_redrawallstructs(viewwsid, PFLAG_ALWAYS);
  1058.     pset_loc_mode(viewwsid, LOCDEV, POP_EVENT, PSWITCH_ECHO);
  1059.     quit = FALSE;
  1060.     do
  1061.     {
  1062.       if (dcopen)
  1063.         pset_disp_upd_st(viewwsid, PDEFER_WAIT, PMODE_NIVE); 
  1064.       pawait_event(0.0, &wsid, &class, &devnum);
  1065.       if ((class == PIN_LOC) && (wsid == viewwsid))
  1066.       {
  1067.         pget_loc(&viewindex, &locpos);
  1068.         geninput.inputclass = PIN_LOC;
  1069.         geninput.ptkugeninput.locpoint = locpos;
  1070.         if (ptk_scanmenus(viewwsid, &geninput, &menuoutput))
  1071.         {
  1072.           pset_loc_mode(viewwsid, LOCDEV, POP_REQ, PSWITCH_ECHO);
  1073.           if (menuoutput.menuid == rot3d1)
  1074.         {
  1075.             if (menuoutput.itemnum == 0)
  1076.               do_moverotator(rot3d1);
  1077.             else
  1078.         {
  1079.               do_rotatevector(&menuoutput, &vup);
  1080.               updatemxvom();
  1081.               updatemxinvvom();
  1082.               updatedcwindow();
  1083.             }
  1084.             ptk_redrawallstructs(viewwsid, PFLAG_ALWAYS);
  1085.           }
  1086.           pset_loc_mode(viewwsid, LOCDEV, POP_EVENT, PSWITCH_ECHO);
  1087.         }
  1088.         else
  1089.         {
  1090.           quit = TRUE;
  1091.         }
  1092.       }
  1093.     } while (!quit);
  1094.   }
  1095.   ptk_unpostmenu(viewwsid, rot3d1);
  1096. } /* do_vup */
  1097.  
  1098. /*--------------------------------------------------------------------------*/
  1099.  
  1100. static void do_prp()
  1101. {
  1102.   Ppoint locpos;
  1103.   ptkboolean quit;
  1104.   Pint wsid, devnum, viewindex;
  1105.   Pin_class class;
  1106.   ptksgeneralinput geninput;
  1107.   ptksmenuoutput menuoutput;
  1108.   Ploc_data locrec;
  1109.   Pview_map3 tempmap;
  1110.  
  1111.   if (dcopen)
  1112.     pset_disp_upd_st(viewwsid, PDEFER_WAIT, PMODE_NIVE);
  1113.   if (!inputmode)
  1114.   {
  1115.     viewmap.proj_ref_point.x = ptk_readfloat(viewwsid, 0.0, 
  1116.                                "Input prp, x (0.0) >", &echoarea);
  1117.     viewmap.proj_ref_point.y = ptk_readfloat(viewwsid, 0.0, 
  1118.                                "Input prp, y (0.0) >", &echoarea);
  1119.     viewmap.proj_ref_point.z = ptk_readfloat(viewwsid, 0.0, 
  1120.                                "Input prp, z (0.0) >", &echoarea);
  1121.     updatemxvmm();
  1122.     updatemxprp();
  1123.     updatemxviewvolume();
  1124.     updatedcwindow();
  1125.     ptk_redrawallstructs(viewwsid, PFLAG_ALWAYS);
  1126.   }
  1127.   else
  1128.   {
  1129.     if (dcopen)
  1130.       pset_disp_upd_st(viewwsid, PDEFER_WAIT, PMODE_NIVE); 
  1131.     ptk_setrotatortitle(rot3d1, "shift prp");
  1132.     ptk_postmenu(viewwsid, rot3d1);
  1133.     ptk_redrawallstructs(viewwsid, PFLAG_ALWAYS);
  1134.     pset_loc_mode(viewwsid, LOCDEV, POP_EVENT, PSWITCH_ECHO);
  1135.     tempmap = viewmap;
  1136.     quit = FALSE;
  1137.     do
  1138.     {
  1139.       pawait_event(0.0, &wsid, &class, &devnum);
  1140.       if ((class == PIN_LOC) && (wsid == viewwsid))
  1141.       {
  1142.         pget_loc(&viewindex, &locpos);
  1143.         geninput.inputclass = PIN_LOC;
  1144.         geninput.ptkugeninput.locpoint = locpos;
  1145.         if (ptk_scanmenus(viewwsid, &geninput, &menuoutput))
  1146.         {
  1147.           pset_loc_mode(viewwsid, LOCDEV, POP_REQ, PSWITCH_ECHO);
  1148.           if (menuoutput.menuid == rot3d1)
  1149.         {
  1150.             if (menuoutput.itemnum == 0)
  1151.               do_moverotator(rot3d1);
  1152.             else
  1153.         {
  1154.               tempmap.proj_ref_point = viewmap.proj_ref_point;
  1155.               do_shiftpoint3(&menuoutput, &tempmap.proj_ref_point);
  1156.               if (checkmapping(&tempmap))
  1157.             {
  1158.                 viewmap.proj_ref_point = tempmap.proj_ref_point;
  1159.                 updatemxvmm();
  1160.                 updatemxprp();
  1161.                 updatemxviewvolume();
  1162.                 updatedcwindow();
  1163.               }
  1164.             }
  1165.             ptk_redrawallstructs(viewwsid, PFLAG_ALWAYS);
  1166.         }
  1167.           pset_loc_mode(viewwsid, LOCDEV, POP_EVENT, PSWITCH_ECHO);
  1168.         }
  1169.         else
  1170.         {
  1171.           quit = TRUE;
  1172.         }
  1173.       }
  1174.     } while (!quit);
  1175.   }
  1176.   ptk_unpostmenu(viewwsid, rot3d1);
  1177. } /* do_prp */
  1178.  
  1179. /*--------------------------------------------------------------------------*/
  1180.  
  1181. static void do_viewplane()
  1182. {
  1183.   Ppoint locpos;
  1184.   ptkboolean quit;
  1185.   Pint wsid, devnum, viewindex;
  1186.   Pin_class class;
  1187.   ptksgeneralinput geninput;
  1188.   ptksmenuoutput menuoutput;
  1189.   Pview_map3 tempmap;
  1190.  
  1191.   if (dcopen)
  1192.     pset_disp_upd_st(viewwsid, PDEFER_WAIT, PMODE_NIVE); 
  1193.   if (!inputmode)
  1194.   {
  1195.     tempmap = viewmap;
  1196.     tempmap.view_plane = ptk_readfloat(viewwsid, 0.0, 
  1197.                        "Input view plane distance (0.0) >", &echoarea);
  1198.     if (checkmapping(&tempmap))
  1199.     {
  1200.       viewmap.view_plane = tempmap.view_plane;
  1201.       updatemxviewplane();
  1202.       updatemxprp();
  1203.       updatemxviewvolume();
  1204.       updatedcwindow();
  1205.       ptk_redrawallstructs(viewwsid, PFLAG_ALWAYS);
  1206.     }
  1207.   }
  1208.   else
  1209.   {
  1210.     ptk_setrotatortitle(rot1d, "shift plane");
  1211.     ptk_postmenu(viewwsid, rot1d);
  1212.     ptk_redrawallstructs(viewwsid, PFLAG_ALWAYS);
  1213.     pset_loc_mode(viewwsid, LOCDEV, POP_EVENT, PSWITCH_ECHO);
  1214.     tempmap = viewmap;
  1215.     quit = FALSE;
  1216.     do
  1217.     {
  1218.       if (dcopen)
  1219.         pset_disp_upd_st(viewwsid, PDEFER_WAIT, PMODE_NIVE); 
  1220.       pawait_event(0.0, &wsid, &class, &devnum);
  1221.       if ((class == PIN_LOC) && (wsid == viewwsid))
  1222.       {
  1223.         pget_loc(&viewindex, &locpos);
  1224.         geninput.inputclass = PIN_LOC;
  1225.         geninput.ptkugeninput.locpoint = locpos;
  1226.         if (ptk_scanmenus(viewwsid, &geninput, &menuoutput))
  1227.         {
  1228.           pset_loc_mode(viewwsid, LOCDEV, POP_REQ, PSWITCH_ECHO);
  1229.           if (menuoutput.menuid == rot1d)
  1230.         {
  1231.             if (menuoutput.itemnum == 0)
  1232.               do_moverotator(rot1d);
  1233.             else
  1234.         {
  1235.               tempmap.view_plane = viewmap.view_plane;
  1236.               switch (menuoutput.itemnum)
  1237.             {
  1238.                 case 1:
  1239.                   tempmap.view_plane += menuoutput.value.y * movefactor;
  1240.                   break;
  1241.   
  1242.                 case 2:
  1243.                   tempmap.view_plane -= (1.0 - menuoutput.value.y) *
  1244.                                          movefactor;
  1245.                   break;
  1246.               }
  1247.               if (checkmapping(&tempmap))
  1248.             {
  1249.                 viewmap.view_plane = tempmap.view_plane;
  1250.                 updatemxviewplane();
  1251.                 updatemxprp();
  1252.                 updatemxviewvolume();
  1253.                 updatedcwindow();
  1254.               }
  1255.             }
  1256.             ptk_redrawallstructs(viewwsid, PFLAG_ALWAYS);
  1257.         }
  1258.           pset_loc_mode(viewwsid, LOCDEV, POP_EVENT, PSWITCH_ECHO);
  1259.         }
  1260.         else
  1261.         {
  1262.           quit = TRUE;
  1263.         }
  1264.       }
  1265.     } while (!quit);
  1266.   }
  1267.   ptk_unpostmenu(viewwsid, rot1d);
  1268. } /* do_viewplane */
  1269.  
  1270. /*--------------------------------------------------------------------------*/
  1271.  
  1272. static void do_frontplane()
  1273. {
  1274.   Ppoint pos, locpos;
  1275.   ptkboolean quit;
  1276.   Pint wsid, devnum, viewindex;
  1277.   Pin_class class;
  1278.   ptksgeneralinput geninput;
  1279.   ptksmenuoutput menuoutput;
  1280.   Pview_map3 tempmap;
  1281.  
  1282.   if (dcopen)
  1283.     pset_disp_upd_st(viewwsid, PDEFER_WAIT, PMODE_NIVE); 
  1284.   if (!inputmode)
  1285.   {
  1286.     tempmap = viewmap;
  1287.     tempmap.front_plane = ptk_readfloat(viewwsid, 0.0, 
  1288.                        "Input front plane distance (0.0) >", &echoarea);
  1289.     if (checkmapping(&tempmap))
  1290.     {
  1291.       viewmap.front_plane = tempmap.front_plane;
  1292.       updatemxviewplane();
  1293.       updatemxprp();
  1294.       updatemxviewvolume();
  1295.       updatedcwindow();
  1296.       ptk_redrawallstructs(viewwsid, PFLAG_ALWAYS);
  1297.     }
  1298.   }
  1299.   else
  1300.   {
  1301.     ptk_setrotatortitle(rot1d, "shift plane");
  1302.     ptk_postmenu(viewwsid, rot1d);
  1303.     ptk_redrawallstructs(viewwsid, PFLAG_ALWAYS);
  1304.     pset_loc_mode(viewwsid, LOCDEV, POP_EVENT, PSWITCH_ECHO);
  1305.     tempmap = viewmap;
  1306.     quit = FALSE;
  1307.     do
  1308.     {
  1309.       if (dcopen)
  1310.         pset_disp_upd_st(viewwsid, PDEFER_WAIT, PMODE_NIVE); 
  1311.       pawait_event(0.0, &wsid, &class, &devnum);
  1312.       if ((class == PIN_LOC) && (wsid == viewwsid))
  1313.       {
  1314.         pget_loc(&viewindex, &locpos);
  1315.         geninput.inputclass = PIN_LOC;
  1316.         geninput.ptkugeninput.locpoint = locpos;
  1317.         if (ptk_scanmenus(viewwsid, &geninput, &menuoutput))
  1318.         {
  1319.           pset_loc_mode(viewwsid, LOCDEV, POP_REQ, PSWITCH_ECHO);
  1320.           if (menuoutput.menuid == rot1d)
  1321.         {
  1322.             if (menuoutput.itemnum == 0)
  1323.               do_moverotator(rot1d);
  1324.             else
  1325.         {
  1326.               tempmap.front_plane = viewmap.front_plane;
  1327.               switch (menuoutput.itemnum)
  1328.             {
  1329.                 case 1:
  1330.                   tempmap.front_plane += menuoutput.value.y * movefactor;
  1331.                   break;
  1332.   
  1333.                 case 2:
  1334.                   tempmap.front_plane -= (1.0 - menuoutput.value.y) * 
  1335.                                           movefactor;
  1336.                   break;
  1337.               }
  1338.               if (checkmapping(&tempmap))
  1339.             {
  1340.                 viewmap.front_plane = tempmap.front_plane;
  1341.                 updatemxvmm();
  1342.                 updatemxviewvolume();
  1343.                 updatedcwindow();
  1344.               }
  1345.             }
  1346.             ptk_redrawallstructs(viewwsid, PFLAG_ALWAYS);
  1347.         }
  1348.           pset_loc_mode(viewwsid, LOCDEV, POP_EVENT, PSWITCH_ECHO);
  1349.         }
  1350.         else
  1351.         {
  1352.           quit = TRUE;
  1353.         }
  1354.       }
  1355.     } while (!quit);
  1356.   }
  1357.   ptk_unpostmenu(viewwsid, rot1d);
  1358. } /* do_frontplane */
  1359.  
  1360. /*--------------------------------------------------------------------------*/
  1361.  
  1362. static void do_backplane()
  1363. {
  1364.   Ppoint locpos;
  1365.   ptkboolean quit;
  1366.   Pint wsid, devnum, viewindex;
  1367.   Pin_class class;
  1368.   ptksgeneralinput geninput;
  1369.   ptksmenuoutput menuoutput;
  1370.   Pview_map3 tempmap;
  1371.  
  1372.   if (dcopen)
  1373.     pset_disp_upd_st(viewwsid, PDEFER_WAIT, PMODE_NIVE); 
  1374.   if (!inputmode)
  1375.   {
  1376.     tempmap = viewmap;
  1377.     tempmap.back_plane = ptk_readfloat(viewwsid, 0.0, 
  1378.                        "Input back plane distance (0.0) >", &echoarea);
  1379.     if (checkmapping(&tempmap))
  1380.     {
  1381.       viewmap.back_plane = tempmap.back_plane;
  1382.       updatemxviewplane();
  1383.       updatemxprp();
  1384.       updatemxviewvolume();
  1385.       updatedcwindow();
  1386.       ptk_redrawallstructs(viewwsid, PFLAG_ALWAYS);
  1387.     }
  1388.   }
  1389.   else
  1390.   {
  1391.     ptk_setrotatortitle(rot1d, "shift plane");
  1392.     ptk_postmenu(viewwsid, rot1d);
  1393.     ptk_redrawallstructs(viewwsid, PFLAG_ALWAYS);
  1394.     pset_loc_mode(viewwsid, LOCDEV, POP_EVENT, PSWITCH_ECHO);
  1395.     tempmap = viewmap;
  1396.     quit = FALSE;
  1397.     do
  1398.     {
  1399.       if (dcopen)
  1400.         pset_disp_upd_st(viewwsid, PDEFER_WAIT, PMODE_NIVE); 
  1401.       pawait_event(0.0, &wsid, &class, &devnum);
  1402.       if ((class == PIN_LOC) && (wsid == viewwsid))
  1403.       {
  1404.         pget_loc(&viewindex, &locpos);
  1405.         geninput.inputclass = PIN_LOC;
  1406.         geninput.ptkugeninput.locpoint = locpos;
  1407.         if (ptk_scanmenus(viewwsid, &geninput, &menuoutput))
  1408.         {
  1409.           pset_loc_mode(viewwsid, LOCDEV, POP_REQ, PSWITCH_ECHO);
  1410.           if (menuoutput.menuid == rot1d)
  1411.         {
  1412.             if (menuoutput.itemnum == 0)
  1413.               do_moverotator(rot1d);
  1414.             else
  1415.         {
  1416.               tempmap.back_plane = viewmap.back_plane;
  1417.               switch (menuoutput.itemnum)
  1418.             {
  1419.                 case 1:
  1420.                   tempmap.back_plane += menuoutput.value.y * movefactor;
  1421.                   break;
  1422.   
  1423.                 case 2:
  1424.                   tempmap.back_plane -= (1.0 - menuoutput.value.y) * 
  1425.                                            movefactor;
  1426.                   break;
  1427.               }
  1428.               if (checkmapping(&tempmap))
  1429.             {
  1430.                 viewmap.back_plane = tempmap.back_plane;
  1431.                 updatemxvmm();
  1432.                 updatemxviewvolume();
  1433.                 updatedcwindow();
  1434.               }
  1435.             }
  1436.             ptk_redrawallstructs(viewwsid, PFLAG_ALWAYS);
  1437.         }
  1438.           pset_loc_mode(viewwsid, LOCDEV, POP_EVENT, PSWITCH_ECHO);
  1439.         }
  1440.         else
  1441.         {
  1442.           quit = TRUE;
  1443.         }
  1444.       }
  1445.     } while (!quit);
  1446.   }
  1447.   ptk_unpostmenu(viewwsid, rot1d);
  1448. } /* do_backplane */
  1449.  
  1450. /*--------------------------------------------------------------------------*/
  1451.  
  1452. static void do_scalewindow(C(ptksmenuoutput *) menuout, C(Plimit *) window)
  1453. PreANSI(ptksmenuoutput *menuout)
  1454. PreANSI(Plimit *window)
  1455. {
  1456.   Ppoint scale;
  1457.  
  1458.   switch (menuout->itemnum)
  1459.   {
  1460.     case 1: /* increase y */
  1461.       scale = ptk_point(1.0, 1.0 + (menuout->value.y * 0.1));
  1462.       break;
  1463.  
  1464.     case 2: /* decrease y */
  1465.       scale = ptk_point(1.0, 1.0 - ((1.0 - menuout->value.y) * 0.1));
  1466.       break;
  1467.  
  1468.     case 3: /* decrease x */
  1469.       scale = ptk_point(1.0 - ((1.0 - menuout->value.x) * 0.1), 1.0);
  1470.       break;
  1471.  
  1472.     case 4: /* increase x */
  1473.       scale = ptk_point(1.0 + (menuout->value.x * 0.1), 1.0);
  1474.       break;
  1475.   }
  1476.   ptk_scalelimits(&scale, window);
  1477. }  /* do_scalewindow */
  1478.  
  1479. /*--------------------------------------------------------------------------*/
  1480.  
  1481. static void do_shiftwindow(C(ptksmenuoutput *) menuout, C(Plimit *) window)
  1482. PreANSI(ptksmenuoutput *menuout)
  1483. PreANSI(Plimit *window)
  1484. {
  1485.   Ppoint shift;
  1486.  
  1487.   switch (menuout->itemnum)
  1488.   {
  1489.     case 1: /* increase y */
  1490.       shift = ptk_point(0.0, (menuout->value.y * movefactor));
  1491.       break;
  1492.  
  1493.     case 2: /* decrease y */
  1494.       shift = ptk_point(0.0, -((1.0 - menuout->value.y) * movefactor));
  1495.       break;
  1496.  
  1497.     case 3: /* decrease x */
  1498.       shift = ptk_point(-((1.0 - menuout->value.x) * movefactor), 0.0);
  1499.       break;
  1500.  
  1501.     case 4: /* increase x */
  1502.       shift = ptk_point((menuout->value.x * movefactor), 0.0);
  1503.       break;
  1504.   }
  1505.   ptk_shiftlimits(&shift, window);
  1506. }  /* do_shiftwindow */
  1507.  
  1508. /*--------------------------------------------------------------------------*/
  1509.  
  1510. static void do_viewwindow()
  1511. {
  1512.   Ppoint locpos;
  1513.   ptkboolean quit;
  1514.   Pint wsid, devnum, viewindex;
  1515.   Pin_class class;
  1516.   ptksgeneralinput geninput;
  1517.   ptksmenuoutput menuoutput;
  1518.   Pview_map3 tempmap;
  1519.  
  1520.   if (dcopen)
  1521.     pset_disp_upd_st(viewwsid, PDEFER_WAIT, PMODE_NIVE); 
  1522.   if (!inputmode)
  1523.   {
  1524.     tempmap = viewmap;
  1525.     tempmap.win.x_min = ptk_readfloat(viewwsid, 0.0, 
  1526.                            "Input window, xmin (0.0) >", &echoarea);
  1527.     tempmap.win.x_max = ptk_readfloat(viewwsid, 1.0, 
  1528.                            "Input window, xmax (1.0) >", &echoarea);
  1529.     tempmap.win.y_min = ptk_readfloat(viewwsid, 0.0, 
  1530.                            "Input window, ymin (0.0) >", &echoarea);
  1531.     tempmap.win.y_max = ptk_readfloat(viewwsid, 1.0, 
  1532.                            "Input window, ymax (1.0) >", &echoarea);
  1533.     if (checkmapping(&tempmap))
  1534.     {
  1535.       viewmap.win = tempmap.win;
  1536.       updatemxviewplane();
  1537.       updatemxvmm();
  1538.       updatemxviewvolume();
  1539.       updatedcwindow();
  1540.       ptk_redrawallstructs(viewwsid, PFLAG_ALWAYS);
  1541.     }
  1542.   }
  1543.   else
  1544.   {
  1545.     ptk_setrotatortitle(rot2d1, "scale window");
  1546.     ptk_setrotatortitle(rot2d2, "shift window");
  1547.     ptk_postmenu(viewwsid, rot2d1);
  1548.     ptk_postmenu(viewwsid, rot2d2);
  1549.     ptk_redrawallstructs(viewwsid, PFLAG_ALWAYS);
  1550.     pset_loc_mode(viewwsid, LOCDEV, POP_EVENT, PSWITCH_ECHO);
  1551.     tempmap = viewmap;
  1552.     quit = FALSE;
  1553.     do
  1554.     {
  1555.       if (dcopen)
  1556.         pset_disp_upd_st(viewwsid, PDEFER_WAIT, PMODE_NIVE); 
  1557.       pawait_event(0.0, &wsid, &class, &devnum);
  1558.       if ((class == PIN_LOC) && (wsid == viewwsid))
  1559.       {
  1560.         pget_loc(&viewindex, &locpos);
  1561.         geninput.inputclass = PIN_LOC;
  1562.         geninput.ptkugeninput.locpoint = locpos;
  1563.         tempmap.win = viewmap.win;
  1564.         if (ptk_scanmenus(viewwsid, &geninput, &menuoutput))
  1565.         {
  1566.           pset_loc_mode(viewwsid, LOCDEV, POP_REQ, PSWITCH_ECHO);
  1567.           if ((menuoutput.menuid == rot2d1) ||
  1568.               (menuoutput.menuid == rot2d2))
  1569.       {
  1570.             if (menuoutput.itemnum == 0)
  1571.               do_moverotator(menuoutput.menuid);
  1572.             else
  1573.         {
  1574.               if (menuoutput.menuid == rot2d1)
  1575.                 do_scalewindow(&menuoutput, &tempmap.win);
  1576.               else
  1577.                 do_shiftwindow(&menuoutput, &tempmap.win);
  1578.               if (checkmapping(&tempmap))
  1579.             {
  1580.                 viewmap.win = tempmap.win;
  1581.                 updatemxviewplane();
  1582.                 updatemxvmm();
  1583.                 updatemxviewvolume();
  1584.                 updatedcwindow();
  1585.               }
  1586.             }
  1587.             ptk_redrawallstructs(viewwsid, PFLAG_ALWAYS);
  1588.         }
  1589.           pset_loc_mode(viewwsid, LOCDEV, POP_EVENT, PSWITCH_ECHO);
  1590.         }
  1591.         else
  1592.         {
  1593.           quit = TRUE;
  1594.         }
  1595.       }
  1596.     } while (!quit);
  1597.   }
  1598.   ptk_unpostmenu(viewwsid, rot2d1);
  1599.   ptk_unpostmenu(viewwsid, rot2d2);
  1600. } /* do_viewwindow */
  1601.  
  1602. /*--------------------------------------------------------------------------*/
  1603.  
  1604. static void do_scaleviewport(C(ptksmenuoutput *) menuout, C(Plimit3 *) vwpt)
  1605. PreANSI(ptksmenuoutput *menuout)
  1606. PreANSI(Plimit3 *vwpt)
  1607. {
  1608.   Ppoint3 scale;
  1609.  
  1610.   switch (menuout->itemnum)
  1611.   {
  1612.     case 1: /* increase y */
  1613.       scale = ptk_point3(1.0, 1.0 + (0.1 * menuout->value.y), 1.0);
  1614.       break;
  1615.  
  1616.     case 2: /* decrease y */
  1617.       scale = ptk_point3(1.0, 1.0 - (0.1 * (1.0 - menuout->value.y)), 1.0);
  1618.       break;
  1619.  
  1620.     case 3: /* decrease x */
  1621.       scale = ptk_point3(1.0 - (0.1 * (1.0 - menuout->value.x)), 1.0, 1.0);
  1622.       break;
  1623.  
  1624.     case 4: /* increase x */
  1625.       scale = ptk_point3(1.0 + (0.1 * menuout->value.x), 1.0, 1.0);
  1626.       break;
  1627.  
  1628.     case 5: /* increase z */
  1629.       scale = ptk_point3(1.0, 1.0, 1.0 + (0.1 * menuout->value.y));
  1630.       break;
  1631.  
  1632.     case 6: /* decrease z */
  1633.       scale = ptk_point3(1.0, 1.0, 1.0 - (0.1 * menuout->value.y));
  1634.       break;
  1635.   }
  1636.   ptk_scalelimits3(&scale, vwpt);
  1637. }  /* do_scaleviewport */
  1638.  
  1639. /*--------------------------------------------------------------------------*/
  1640.  
  1641. static void do_shiftviewport(C(ptksmenuoutput *) menuout, C(Plimit3 *) vwpt)
  1642. PreANSI(ptksmenuoutput *menuout)
  1643. PreANSI(Plimit3 *vwpt)
  1644. {
  1645.   Ppoint3 shift;
  1646.   Pfloat shiftfactor;
  1647.  
  1648.   shiftfactor = 0.1;
  1649.   switch (menuout->itemnum)
  1650.   {
  1651.     case 1: /* increase y */
  1652.       shift = ptk_point3(0.0, (menuout->value.y * shiftfactor), 0.0);
  1653.       break;
  1654.  
  1655.     case 2: /* decrease y */
  1656.       shift = ptk_point3(0.0, -((1.0 - menuout->value.y) * shiftfactor), 0.0);
  1657.       break;
  1658.  
  1659.     case 3: /* decrease x */
  1660.       shift = ptk_point3(-((1.0 - menuout->value.x) * shiftfactor), 0.0, 0.0);
  1661.       break;
  1662.  
  1663.     case 4: /* increase x */
  1664.       shift = ptk_point3((menuout->value.x * shiftfactor), 0.0, 0.0);
  1665.       break;
  1666.  
  1667.     case 5: /* increase z */
  1668.       shift = ptk_point3(0.0, 0.0, (menuout->value.y * shiftfactor));
  1669.       break;
  1670.  
  1671.     case 6: /* decrease z */
  1672.       shift = ptk_point3(0.0, 0.0, -(menuout->value.y * shiftfactor));
  1673.       break;
  1674.   }
  1675.   ptk_shiftlimits3(&shift, vwpt);
  1676. }  /* do_shiftviewport */
  1677.  
  1678. /*--------------------------------------------------------------------------*/
  1679.  
  1680. static void do_projviewport()
  1681. {
  1682.   Ppoint locpos;
  1683.   ptkboolean projvwptquit;
  1684.   Pint wsid, devnum, viewindex;
  1685.   Pin_class class;
  1686.   ptksgeneralinput geninput;
  1687.   ptksmenuoutput menuoutput;
  1688.   Pview_map3 tempmap;
  1689.  
  1690.   if (dcopen)
  1691.     pset_disp_upd_st(viewwsid, PDEFER_WAIT, PMODE_NIVE); 
  1692.   if (!inputmode)
  1693.   {
  1694.     tempmap = viewmap;
  1695.     tempmap.proj_vp.x_min = ptk_readfloat(viewwsid, 0.0, 
  1696.                            "Input viewport, xmin (0.0) >", &echoarea);
  1697.     tempmap.proj_vp.x_max = ptk_readfloat(viewwsid, 1.0, 
  1698.                            "Input viewport, xmax (1.0) >", &echoarea);
  1699.     tempmap.proj_vp.y_min = ptk_readfloat(viewwsid, 0.0, 
  1700.                            "Input viewport, ymin (0.0) >", &echoarea);
  1701.     tempmap.proj_vp.y_max = ptk_readfloat(viewwsid, 1.0, 
  1702.                            "Input viewport, ymax (1.0) >", &echoarea);
  1703.     tempmap.proj_vp.z_min = ptk_readfloat(viewwsid, 0.0, 
  1704.                            "Input viewport, zmin (0.0) >", &echoarea);
  1705.     tempmap.proj_vp.z_max = ptk_readfloat(viewwsid, 1.0, 
  1706.                            "Input viewport, zmax (1.0) >", &echoarea);
  1707.     if (checkmapping(&tempmap))
  1708.     {
  1709.       viewmap.proj_vp = tempmap.proj_vp;
  1710.       updatemxvmm();
  1711.       updatemxprojviewport();
  1712.       updatedcwindow();
  1713.       ptk_redrawallstructs(viewwsid, PFLAG_ALWAYS);
  1714.     }
  1715.   }
  1716.   else
  1717.   {
  1718.     ptk_setrotatortitle(rot3d1, "scale viewport");
  1719.     ptk_setrotatortitle(rot3d2, "shift viewport");
  1720.     ptk_postmenu(viewwsid, rot3d1);
  1721.     ptk_postmenu(viewwsid, rot3d2);
  1722.     ptk_redrawallstructs(viewwsid, PFLAG_ALWAYS);
  1723.     pset_loc_mode(viewwsid, LOCDEV, POP_EVENT, PSWITCH_ECHO);
  1724.     tempmap = viewmap;
  1725.     projvwptquit = FALSE;
  1726.     do
  1727.     {
  1728.       if (dcopen)
  1729.         pset_disp_upd_st(viewwsid, PDEFER_WAIT, PMODE_NIVE); 
  1730.       pawait_event(0.0, &wsid, &class, &devnum);
  1731.       if ((class == PIN_LOC) && (wsid == viewwsid))
  1732.       {
  1733.         pget_loc(&viewindex, &locpos);
  1734.         geninput.inputclass = PIN_LOC;
  1735.         geninput.ptkugeninput.locpoint = locpos;
  1736.         tempmap.proj_vp = viewmap.proj_vp;
  1737.         if (ptk_scanmenus(viewwsid, &geninput, &menuoutput))
  1738.         {
  1739.           pset_loc_mode(viewwsid, LOCDEV, POP_REQ, PSWITCH_ECHO);
  1740.           if ((menuoutput.menuid == rot3d1) ||
  1741.               (menuoutput.menuid == rot3d2))
  1742.         {
  1743.             if (menuoutput.itemnum == 0)
  1744.               do_moverotator(menuoutput.menuid);
  1745.             else
  1746.         {
  1747.               if (menuoutput.menuid == rot3d1)
  1748.                 do_scaleviewport(&menuoutput, &tempmap.proj_vp);
  1749.               else
  1750.                 do_shiftviewport(&menuoutput, &tempmap.proj_vp);
  1751.               if (checkmapping(&tempmap))
  1752.             {
  1753.                 viewmap.proj_vp = tempmap.proj_vp;
  1754.                 updatemxvmm();
  1755.                 updatemxprojviewport();
  1756.                 updatedcwindow();
  1757.               }
  1758.             }
  1759.             ptk_redrawallstructs(viewwsid, PFLAG_ALWAYS);
  1760.         }
  1761.           pset_loc_mode(viewwsid, LOCDEV, POP_EVENT, PSWITCH_ECHO);
  1762.         }
  1763.         else
  1764.         {
  1765.           projvwptquit = TRUE;
  1766.         }
  1767.       }
  1768.     } while (!projvwptquit);
  1769.   }
  1770.   ptk_unpostmenu(viewwsid, rot3d1);
  1771.   ptk_unpostmenu(viewwsid, rot3d2);
  1772. } /* do_projviewport */
  1773.  
  1774. /*--------------------------------------------------------------------------*/
  1775.  
  1776. static void do_projection()
  1777. {
  1778.   if (dcopen)
  1779.     pset_disp_upd_st(viewwsid, PDEFER_WAIT, PMODE_NIVE); 
  1780.   if (viewmap.proj_type == PTYPE_PARAL)
  1781.     viewmap.proj_type = PTYPE_PERSPECT;
  1782.   else
  1783.     viewmap.proj_type = PTYPE_PARAL;
  1784.   updatemxvmm();
  1785.   updatedcwindow();
  1786. } /* do_projection */
  1787.  
  1788. /*--------------------------------------------------------------------------*/
  1789.  
  1790. static void do_inquire()
  1791. {
  1792.   pset_disp_upd_st(viewwsid, PDEFER_WAIT, PMODE_NIVE); 
  1793.   ptk_printfterminal(terminalwindow, "vrp = %f, %f, %f\n", vrp.x, vrp.y,
  1794.                      vrp.z);
  1795.   ptk_printfterminal(terminalwindow, "vpn = %f, %f, %f\n", vpn.x, vpn.y,
  1796.                      vpn.z);
  1797.   ptk_printfterminal(terminalwindow, "vup = %f, %f, %f\n", vup.x, vup.y,
  1798.                      vup.z);
  1799.   ptk_printfterminal(terminalwindow, "prp = %f, %f, %f\n", viewmap.proj_ref_point.x, 
  1800.                      viewmap.proj_ref_point.y, viewmap.proj_ref_point.z);
  1801.   ptk_printfterminal(terminalwindow, "view plane = %f\n", 
  1802.                      viewmap.view_plane);  
  1803.   ptk_printfterminal(terminalwindow, "front plane = %f\n", 
  1804.                      viewmap.front_plane);
  1805.   ptk_printfterminal(terminalwindow, "back plane = %f\n", 
  1806.                      viewmap.back_plane);
  1807.   ptk_writelnterminal(terminalwindow, "view window:");
  1808.   ptk_printfterminal(terminalwindow, "xmin = %f, xmax = %f\n", 
  1809.                      viewmap.win.x_min, viewmap.win.x_max);
  1810.   ptk_printfterminal(terminalwindow, "ymin = %f, ymax = %f\n", 
  1811.                      viewmap.win.y_min, viewmap.win.y_max);
  1812.   ptk_writelnterminal(terminalwindow, "projection viewport:");
  1813.   ptk_printfterminal(terminalwindow, "xmin = %f, xmax = %f\n", 
  1814.                      viewmap.proj_vp.x_min, viewmap.proj_vp.x_max);
  1815.   ptk_printfterminal(terminalwindow, "ymin = %f, ymax = %f\n", 
  1816.                      viewmap.proj_vp.y_min, viewmap.proj_vp.y_max);
  1817.   ptk_printfterminal(terminalwindow, "zmin = %f, zmax = %f\n", 
  1818.                      viewmap.proj_vp.z_min, viewmap.proj_vp.z_max);
  1819.   ptk_redrawallstructs(viewwsid, PFLAG_ALWAYS);
  1820. } /* do_inquire */
  1821.  
  1822. /*--------------------------------------------------------------------------*/
  1823.  
  1824. static void makemenus(C(void))
  1825. {
  1826.   Pint err;
  1827.   Ppoint topleft;
  1828.   Ppoint box, size, pos;
  1829.  
  1830.   /* view menu */
  1831.   viewmenuid = ptk_stringtoint("menuid", "ptk$viewmenu"); 
  1832.   box = ptk_point(0.1, 0.05);
  1833.   topleft = ptk_point(0.0, 1.0);
  1834.   ptk_createboxmenu(viewmenuid, &topleft, &box);
  1835.   ptk_setboxmenuattrs(viewwsid, viewmenuid, PPATH_DOWN, menutextfont, 
  1836.                     menutextcolourind, menucolourind,
  1837.                     bannercolourind, tlcolourind, brcolourind,
  1838.                     menutextcolourind, menucolourind, menucolourind);
  1839.  
  1840.   ptk_createtextmenuitem(viewmenuid, "orient'n", 1, PEDIT_INSERT, &err);
  1841.   ptk_createtextmenuitem(viewmenuid, "mapping", 2, PEDIT_INSERT, &err);
  1842.   ptk_createtextmenuitem(viewmenuid, "clipping", 3, PEDIT_INSERT, &err);
  1843.   ptk_createtextmenuitem(viewmenuid, "reset", 4, PEDIT_INSERT, &err);
  1844.   ptk_createtextmenuitem(viewmenuid, "keyboard", 5, PEDIT_INSERT, &err);
  1845.   ptk_createtextmenuitem(viewmenuid, "inquire", 6, PEDIT_INSERT, &err);
  1846.   ptk_createtextmenuitem(viewmenuid, "refresh", 7, PEDIT_INSERT, &err);
  1847.   ptk_createtextmenuitem(viewmenuid, "exit", 8, PEDIT_INSERT, &err);
  1848.  
  1849.   /* view orientation menu */
  1850.   orimenuid = ptk_stringtoint("menuid", "ptk$orientationmenu"); 
  1851.   box = ptk_point(0.1, 0.05);
  1852.   topleft = ptk_point(0.0, 1.0);
  1853.   ptk_createboxmenu(orimenuid, &topleft, &box);
  1854.   ptk_setboxmenuattrs(viewwsid, orimenuid, PPATH_DOWN, menutextfont, 
  1855.                     menutextcolourind, menucolourind,
  1856.                     bannercolourind, tlcolourind, brcolourind,
  1857.                     menutextcolourind, menucolourind, menucolourind);
  1858.  
  1859.   ptk_createtextmenuitem(orimenuid, "vrp", 1, PEDIT_INSERT, &err);
  1860.   ptk_createtextmenuitem(orimenuid, "vpn", 2, PEDIT_INSERT, &err);
  1861.   ptk_createtextmenuitem(orimenuid, "vup", 3, PEDIT_INSERT, &err);
  1862.  
  1863.   /* view clipping menu */
  1864.   clipmenuid = ptk_stringtoint("menuid", "ptk$clippingmenu"); 
  1865.   box = ptk_point(0.1, 0.05);
  1866.   topleft = ptk_point(0.0, 1.0);
  1867.   ptk_createboxmenu(clipmenuid, &topleft, &box); 
  1868.   ptk_setboxmenuattrs(viewwsid, clipmenuid, PPATH_DOWN, menutextfont, 
  1869.                     menutextcolourind, menucolourind,
  1870.                     bannercolourind, tlcolourind, brcolourind,
  1871.                     menutextcolourind, menucolourind, menucolourind);
  1872.  
  1873.   ptk_createtextmenuitem(clipmenuid, "x-y ON", 1, PEDIT_INSERT, &err);
  1874.   ptk_createtextmenuitem(clipmenuid, "front ON", 2, PEDIT_INSERT, &err);
  1875.   ptk_createtextmenuitem(clipmenuid, "back ON", 3, PEDIT_INSERT, &err);
  1876.  
  1877.   /* view mapping menu */
  1878.   mapmenuid = ptk_stringtoint("menuid", "ptk$mappingmenu"); 
  1879.   box = ptk_point(0.1, 0.05);
  1880.   topleft = ptk_point(0.0, 1.0);
  1881.   ptk_createboxmenu(mapmenuid, &topleft, &box);
  1882.   ptk_setboxmenuattrs(viewwsid, mapmenuid, PPATH_DOWN, menutextfont, 
  1883.                     menutextcolourind, menucolourind,
  1884.                     bannercolourind, tlcolourind, brcolourind,
  1885.                     menutextcolourind, menucolourind, menucolourind);
  1886.  
  1887.   ptk_createtextmenuitem(mapmenuid, "prp", 1, PEDIT_INSERT, &err);
  1888.   ptk_createtextmenuitem(mapmenuid, "front pl.", 2, PEDIT_INSERT, &err);
  1889.   ptk_createtextmenuitem(mapmenuid, "back pl.", 3, PEDIT_INSERT, &err);
  1890.   ptk_createtextmenuitem(mapmenuid, "view pl.", 4, PEDIT_INSERT, &err);
  1891.   ptk_createtextmenuitem(mapmenuid, "window", 5, PEDIT_INSERT, &err);
  1892.   ptk_createtextmenuitem(mapmenuid, "viewport", 6, PEDIT_INSERT, &err);
  1893.   ptk_createtextmenuitem(mapmenuid, "perspective", 7, PEDIT_INSERT, &err);
  1894.  
  1895.   /* window menu */
  1896.   windowmenuid = ptk_stringtoint("menuid", "ptk$windowmenu"); 
  1897.   box = ptk_point(0.1, 0.05);
  1898.   topleft = ptk_point(0.0, 1.0);
  1899.   ptk_createboxmenu(windowmenuid, &topleft, &box);
  1900.   ptk_setboxmenuattrs(viewwsid, windowmenuid, PPATH_DOWN, menutextfont, 
  1901.                     menutextcolourind, menucolourind,
  1902.                     bannercolourind, tlcolourind, brcolourind,
  1903.                     menutextcolourind, menucolourind, menucolourind);
  1904.  
  1905.   ptk_createtextmenuitem(windowmenuid, "close", 1, PEDIT_INSERT, &err);
  1906.   ptk_createtextmenuitem(windowmenuid, "move", 2, PEDIT_INSERT, &err);
  1907.   ptk_createtextmenuitem(windowmenuid, "resize", 3, PEDIT_INSERT, &err);
  1908.   ptk_createtextmenuitem(windowmenuid, "front", 4, PEDIT_INSERT, &err);
  1909.   ptk_createtextmenuitem(windowmenuid, "back", 5, PEDIT_INSERT, &err);
  1910.   ptk_createtextmenuitem(windowmenuid, "camera", 6, PEDIT_INSERT, &err);
  1911.  
  1912.  /* camera interface */
  1913.   
  1914.   /* rotators */
  1915.   rot3d1 = ptk_stringtoint("menuid", "ptk$rotator3d1"); 
  1916.   rot3d2 = ptk_stringtoint("menuid", "ptk$rotator3d2"); 
  1917.   rot2d1 = ptk_stringtoint("menuid", "ptk$rotator2d1"); 
  1918.   rot2d2 = ptk_stringtoint("menuid", "ptk$rotator2d2"); 
  1919.   rot1d = ptk_stringtoint("menuid", "ptk$rotator1d"); 
  1920.   rot3d1pos = ptk_point(0.15, 0.88);
  1921.   rot3d2pos = ptk_point(0.15, 0.66);
  1922.   rot2d1pos = ptk_point(0.1, 0.88);
  1923.   rot2d2pos = ptk_point(0.1, 0.66);
  1924.   rot1dpos = ptk_point(0.1, 0.66);
  1925.   size = ptk_point(0.3, 0.2);
  1926.   ptk_createrotator(viewwsid, rot3d1, PTKETHREED, &size, "rotator",
  1927.                     0.02);
  1928.   ptk_setrotatorattrs(viewwsid, rot3d1, windowtextfont, bannertextcolourind, 
  1929.                     arrowcolourind, arrowedgecolourind, 
  1930.                     windowcolourind, bannercolourind,
  1931.                     bannercolourind, tlcolourind, brcolourind);
  1932.   ptk_createrotator(viewwsid, rot3d2, PTKETHREED, &size, "rotator",
  1933.                     0.02);
  1934.   ptk_setrotatorattrs(viewwsid, rot3d2, windowtextfont, bannertextcolourind, 
  1935.                     arrowcolourind, arrowedgecolourind, 
  1936.                     windowcolourind, bannercolourind,
  1937.                     bannercolourind, tlcolourind, brcolourind);
  1938.   size = ptk_point(0.2, 0.2);
  1939.   ptk_createrotator(viewwsid, rot2d1, PTKETWOD, &size, "rotator",
  1940.                     0.02);
  1941.   ptk_setrotatorattrs(viewwsid, rot2d1, windowtextfont, bannertextcolourind, 
  1942.                     arrowcolourind, arrowedgecolourind, 
  1943.                     windowcolourind, bannercolourind,
  1944.                     bannercolourind, tlcolourind, brcolourind);
  1945.   ptk_createrotator(viewwsid, rot2d2, PTKETWOD, &size, "rotator",
  1946.                     0.02);
  1947.   ptk_setrotatorattrs(viewwsid, rot2d2, windowtextfont, bannertextcolourind, 
  1948.                     arrowcolourind, arrowedgecolourind, 
  1949.                     windowcolourind, bannercolourind,
  1950.                     bannercolourind, tlcolourind, brcolourind);
  1951.   ptk_createrotator(viewwsid, rot1d, PTKEONED, &size, "rotator",
  1952.                     0.02);
  1953.   ptk_setrotatorattrs(viewwsid, rot1d, windowtextfont, bannertextcolourind, 
  1954.                     arrowcolourind, arrowedgecolourind, 
  1955.                     windowcolourind, bannercolourind,
  1956.                     bannercolourind, tlcolourind, brcolourind);
  1957.   ptk_setmenuposition(rot3d1, &rot3d1pos);
  1958.   ptk_setmenuposition(rot3d2, &rot3d2pos);
  1959.   ptk_setmenuposition(rot2d1, &rot2d1pos);
  1960.   ptk_setmenuposition(rot2d2, &rot2d2pos);
  1961.   ptk_setmenuposition(rot1d, &rot1dpos);
  1962. }  /* makemenus */
  1963.  
  1964. /*--------------------------------------------------------------------------*/
  1965.  
  1966. static void do_scrollterminal()
  1967. {
  1968.   ptkboolean quit;
  1969.   Pint ws, devnum;
  1970.   Pin_class class;
  1971.   Ppoint position;
  1972.   Pint view_index;
  1973.   ptksgeneralinput geninput;
  1974.   ptksmenuoutput menuoutput;
  1975.   Ploc_data locrec;
  1976.   Ptext_path direction;
  1977.   Pint numlines, maxlines, maxcolumns, txfont, txcolour, err;
  1978.  
  1979.   ptk_setrotatortitle(rot1d, "scroll terminal");
  1980.   ptk_postmenu(viewwsid, rot1d);
  1981.   ptk_redrawallstructs(viewwsid, PFLAG_ALWAYS);
  1982.   pset_loc_mode(viewwsid, LOCDEV, POP_EVENT, PSWITCH_ECHO);
  1983.   quit = FALSE;
  1984.   ptk_inqterminaldata(terminalwindow, &maxlines, &maxcolumns, &txfont,
  1985.                       &txcolour, &err);
  1986.   do
  1987.   {
  1988.     pset_disp_upd_st(viewwsid, PDEFER_WAIT, PMODE_NIVE);
  1989.     pawait_event(0.0, &ws, &class, &devnum);
  1990.     if ((class == PIN_LOC) && (ws == viewwsid))
  1991.     {
  1992.       pget_loc(&view_index, &position);
  1993.       geninput.inputclass = PIN_LOC;
  1994.       geninput.ptkugeninput.locpoint = position;
  1995.       if (ptk_scanmenus(viewwsid, &geninput, &menuoutput))
  1996.       {
  1997.         pset_loc_mode(viewwsid, LOCDEV, POP_REQ, PSWITCH_ECHO);
  1998.         if (menuoutput.menuid == rot1d)
  1999.     {
  2000.           if (menuoutput.itemnum == 0)
  2001.             do_moverotator(rot1d);
  2002.           else
  2003.       {
  2004.             switch (menuoutput.itemnum)
  2005.         {
  2006.           case 1:
  2007.                 direction = PPATH_DOWN;
  2008.                 numlines = (Pint)(menuoutput.value.y * (Pfloat)maxlines);
  2009.                 break;
  2010.  
  2011.           case 2:
  2012.                 direction = PPATH_UP;
  2013.                 numlines = (Pint)((1.0 - menuoutput.value.y) * 
  2014.                                   (Pfloat)maxlines);
  2015.                 break;
  2016.         }
  2017.             ptk_scrollterminal(terminalwindow, direction, numlines);
  2018.             ptk_redrawallstructs(viewwsid, PFLAG_ALWAYS);
  2019.           }
  2020.     }
  2021.         pset_loc_mode(viewwsid, LOCDEV, POP_EVENT, PSWITCH_ECHO);
  2022.       }
  2023.       else
  2024.       {
  2025.         quit = TRUE;
  2026.       }
  2027.     }
  2028.   } while (!quit);
  2029.   ptk_unpostmenu(viewwsid, rot1d);
  2030. } /* do_scrollterminal */
  2031.  
  2032. /*--------------------------------------------------------------------------*/
  2033.  
  2034. static void do_spincamera(C(Pint) windid, C(ptksmenuoutput *) menuout)
  2035. PreANSI(Pint windid)
  2036. PreANSI(ptksmenuoutput *menuout)
  2037. {
  2038.   Pfloat angle;
  2039.  
  2040.   switch (menuout->itemnum)
  2041.   {
  2042.     case 1:
  2043.       angle = menuout->value.y * 10.0;
  2044.       ptk_rotatepositionxaxis(windid, angle);
  2045.       break;
  2046.  
  2047.     case 2:
  2048.       angle = (1.0 - menuout->value.y) * 10.0;
  2049.       ptk_rotatepositionxaxis(windid, -angle);
  2050.       break;
  2051.  
  2052.     case 3:
  2053.       angle = (1.0 - menuout->value.x) * 10.0;
  2054.       ptk_rotatepositionyaxis(windid, angle);
  2055.       break;
  2056.  
  2057.     case 4:
  2058.       angle = menuout->value.x * 10.0;
  2059.       ptk_rotatepositionyaxis(windid, -angle);
  2060.       break;
  2061.  
  2062.     case 5:
  2063.       angle = menuout->value.y * 10.0;
  2064.       ptk_rotatecameraupvector(windid, angle);
  2065.       break;
  2066.  
  2067.     case 6:
  2068.       angle = menuout->value.y * 10.0;
  2069.       ptk_rotatecameraupvector(windid, -angle);
  2070.       break;
  2071.   }
  2072. }  /* do_spincamera */
  2073.  
  2074. /*--------------------------------------------------------------------------*/
  2075.  
  2076. static void do_zoompancamera(C(Pint) windid, C(ptksmenuoutput *) menuout)
  2077. PreANSI(Pint windid)
  2078. PreANSI(ptksmenuoutput *menuout)
  2079. {
  2080.   Pfloat zoomfactor, xsize, ysize;
  2081.   Ppoint3 shift;
  2082.   Plimit3 limits;
  2083.   Pint err;
  2084.  
  2085.   ptk_inqcameralimits(windid, &limits, &err);
  2086.   xsize = limits.x_max - limits.x_min;
  2087.   ysize = limits.y_max - limits.y_min;
  2088.   xsize /= 2.0;
  2089.   ysize /= 2.0;
  2090.   switch (menuout->itemnum)
  2091.   {
  2092.     case 1:
  2093.       shift = ptk_point3(0.0, menuout->value.y * ysize, 0.0);
  2094.       ptk_shiftcamera(windid, &shift);
  2095.       break;
  2096.  
  2097.     case 2:
  2098.       shift = ptk_point3(0.0, -(1.0 - menuout->value.y) * ysize, 0.0);
  2099.       ptk_shiftcamera(windid, &shift); 
  2100.       break;
  2101.  
  2102.     case 3:
  2103.       shift = ptk_point3(-(1.0 - menuout->value.x) * xsize, 0.0, 0.0);
  2104.       ptk_shiftcamera(windid, &shift);
  2105.       break;
  2106.  
  2107.     case 4:
  2108.       shift = ptk_point3(menuout->value.x * xsize, 0.0, 0.0);
  2109.       ptk_shiftcamera(windid, &shift);
  2110.       break;
  2111.  
  2112.     case 5:
  2113.       zoomfactor = menuout->value.y * 0.1;
  2114.       ptk_scaleviewwindow(windid, 1.0 - zoomfactor);
  2115.       break;
  2116.  
  2117.     case 6:
  2118.       zoomfactor = menuout->value.y * 0.1;
  2119.       ptk_scaleviewwindow(windid, 1.0 + zoomfactor);
  2120.       break;
  2121.   }
  2122. }  /* do_zoompancamera */
  2123.  
  2124. /*--------------------------------------------------------------------------*/
  2125.  
  2126. static void camerainterface(C(Pint) windid)
  2127. PreANSI(Pint windid)
  2128. {
  2129.   Ppoint locpos;
  2130.   ptkboolean cameraquit;
  2131.   Pint wsid, devnum, viewindex;
  2132.   Pin_class class;
  2133.   ptksgeneralinput geninput;
  2134.   ptksmenuoutput menuoutput;
  2135.   Ploc_data locrec;
  2136.  
  2137.   ptk_setrotatortitle(rot3d1, "rotate");
  2138.   ptk_setrotatortitle(rot3d2, "zoom + pan");
  2139.   ptk_postmenu(viewwsid, rot3d1);
  2140.   ptk_postmenu(viewwsid, rot3d2);
  2141.   ptk_redrawallstructs(viewwsid, PFLAG_ALWAYS);
  2142.   pset_loc_mode(viewwsid, LOCDEV, POP_EVENT, PSWITCH_ECHO);
  2143.   cameraquit = FALSE;
  2144.   do
  2145.   {
  2146.     pset_disp_upd_st(viewwsid, PDEFER_WAIT, PMODE_NIVE); 
  2147.     pawait_event(0.0, &wsid, &class, &devnum);
  2148.     if ((class == PIN_LOC) && (wsid == viewwsid))
  2149.     {
  2150.       pget_loc(&viewindex, &locpos);
  2151.       geninput.inputclass = PIN_LOC;
  2152.       geninput.ptkugeninput.locpoint = locpos;
  2153.       if (ptk_scanmenus(viewwsid, &geninput, &menuoutput))
  2154.       {
  2155.         pset_loc_mode(viewwsid, LOCDEV, POP_REQ, PSWITCH_ECHO);
  2156.         if (menuoutput.menuid == rot3d1)
  2157.     {
  2158.           if (menuoutput.itemnum == 0)
  2159.             do_moverotator(rot3d1);
  2160.           else
  2161.             do_spincamera(windid, &menuoutput);
  2162.           ptk_redrawallstructs(viewwsid, PFLAG_ALWAYS);
  2163.     }
  2164.         else
  2165.         if (menuoutput.menuid == rot3d2)
  2166.     {
  2167.           if (menuoutput.itemnum == 0)
  2168.             do_moverotator(rot3d2);
  2169.           else
  2170.             do_zoompancamera(windid, &menuoutput);
  2171.           ptk_redrawallstructs(viewwsid, PFLAG_ALWAYS);
  2172.     }
  2173.         pset_loc_mode(viewwsid, LOCDEV, POP_EVENT, PSWITCH_ECHO);
  2174.       }
  2175.       else
  2176.       {
  2177.         cameraquit = TRUE;
  2178.       }
  2179.     }
  2180.   } while (!cameraquit);
  2181.   ptk_unpostmenu(viewwsid, rot3d1);
  2182.   ptk_unpostmenu(viewwsid, rot3d2);
  2183. }  /* camerainterface */
  2184.  
  2185. /*--------------------------------------------------------------------------*/
  2186.  
  2187. static void do_orimenu(C(Pint) menuitem)
  2188. PreANSI(Pint menuitem)
  2189. {
  2190.   ptk_unpostallmenu(viewwsid);   
  2191.   switch (menuitem)
  2192.   {
  2193.     case 1: /* view reference point */ 
  2194.       do_vrp(); 
  2195.       break;
  2196.  
  2197.     case 2: /* view plane normal */ 
  2198.       do_vpn();
  2199.       break;
  2200.  
  2201.     case 3: /* view up vector */
  2202.       do_vup();
  2203.       break;
  2204.   }  
  2205.   curmenu = 0;
  2206. }  /* do_orimenu */
  2207.  
  2208. /*--------------------------------------------------------------------------*/
  2209.  
  2210. static void do_clipmenu(C(Pint) menuitem)
  2211. PreANSI(Pint menuitem)
  2212. {
  2213.   Pint err;
  2214.  
  2215.   switch (menuitem)
  2216.   {
  2217.     case 1:  
  2218.       if (clipxy == PIND_NO_CLIP)
  2219.       {
  2220.         ptk_createtextmenuitem(clipmenuid, "x-y OFF", 1, PEDIT_REPLACE, &err);
  2221.         clipxy = PIND_CLIP;
  2222.       }
  2223.       else
  2224.       {
  2225.         ptk_createtextmenuitem(clipmenuid, "x-y ON", 1, PEDIT_REPLACE, &err);
  2226.         clipxy = PIND_NO_CLIP;
  2227.       }
  2228.       break;
  2229.  
  2230.     case 2: 
  2231.       if (clipfront == PIND_NO_CLIP)
  2232.       {
  2233.         ptk_createtextmenuitem(clipmenuid, "front OFF", 2, PEDIT_REPLACE, &err);
  2234.         clipfront = PIND_CLIP;
  2235.       }
  2236.       else
  2237.       {
  2238.         ptk_createtextmenuitem(clipmenuid, "front ON", 2, PEDIT_REPLACE, &err);
  2239.         clipfront = PIND_NO_CLIP;
  2240.       }
  2241.       break;
  2242.  
  2243.     case 3: 
  2244.       if (clipback == PIND_NO_CLIP)
  2245.       {
  2246.         ptk_createtextmenuitem(clipmenuid, "back OFF", 3, PEDIT_REPLACE, &err);
  2247.         clipback = PIND_CLIP;
  2248.       }
  2249.       else
  2250.       {
  2251.         ptk_createtextmenuitem(clipmenuid, "back ON", 3, PEDIT_REPLACE, &err);
  2252.         clipback = PIND_NO_CLIP;
  2253.       }
  2254.  
  2255.       break;
  2256.   }  
  2257.   ptk_setviewclipping3(dcwindow, &viewmap.proj_vp, clipxy, clipfront, 
  2258.                        clipback);
  2259. }  /* do_clipmenu */
  2260.  
  2261. /*--------------------------------------------------------------------------*/
  2262.  
  2263. static void do_mapmenu(C(Pint) menuitem)
  2264. PreANSI(Pint menuitem)
  2265. {
  2266.   Pint err;
  2267.  
  2268.   if (menuitem != 7)
  2269.   {
  2270.     ptk_unpostallmenu(viewwsid);
  2271.     curmenu = 0;
  2272.   }
  2273.   switch (menuitem)
  2274.   {
  2275.     case 1: /* prp */ 
  2276.       do_prp();
  2277.       break;
  2278.  
  2279.     case 2: /* front plane distance */
  2280.       do_frontplane(); 
  2281.       break;
  2282.  
  2283.     case 3: /* back plane distance */
  2284.       do_backplane();
  2285.       break;
  2286.  
  2287.     case 4: /* view plane distance */
  2288.       do_viewplane();
  2289.       break;
  2290.  
  2291.     case 5: /* view window limits */
  2292.       do_viewwindow();
  2293.       break;
  2294.  
  2295.     case 6: /* projection viewport limits */
  2296.       do_projviewport();
  2297.       break;
  2298.  
  2299.     case 7: /* projection type */
  2300.       do_projection();
  2301.       if (viewmap.proj_type == PTYPE_PARAL)
  2302.         ptk_createtextmenuitem(mapmenuid, "perspective", 7, PEDIT_REPLACE, 
  2303.                                &err);
  2304.       else
  2305.         ptk_createtextmenuitem(mapmenuid, "parallel", 7, PEDIT_REPLACE, &err);
  2306.       break;
  2307.   }  
  2308. }  /* do_mapmenu */
  2309.  
  2310. /*--------------------------------------------------------------------------*/
  2311.  
  2312. static void do_viewmenu(C(Pint) menuitem, C(Ppoint *) pos)
  2313. PreANSI(Pint menuitem)
  2314. PreANSI(Ppoint *pos)
  2315. {
  2316.   Pint err;
  2317.   Pfloat maxscenevol;
  2318.  
  2319.   switch (menuitem)
  2320.   {
  2321.     case 1: /* orientation */
  2322.       ptk_setmenuposition(orimenuid, pos);
  2323.       ptk_postmenu(viewwsid, orimenuid);
  2324.       ptk_unpostmenu(viewwsid, mapmenuid);
  2325.       ptk_unpostmenu(viewwsid, clipmenuid);
  2326.       ptk_redrawallstructs(viewwsid, PFLAG_ALWAYS);
  2327.       break;
  2328.  
  2329.     case 2: /* mapping */
  2330.       ptk_setmenuposition(mapmenuid, pos);
  2331.       ptk_postmenu(viewwsid, mapmenuid);
  2332.       ptk_unpostmenu(viewwsid, orimenuid);
  2333.       ptk_unpostmenu(viewwsid, clipmenuid);
  2334.       ptk_redrawallstructs(viewwsid, PFLAG_ALWAYS);
  2335.       break;
  2336.  
  2337.     case 3: /* clipping */
  2338.       ptk_setmenuposition(clipmenuid, pos);
  2339.       ptk_postmenu(viewwsid, clipmenuid);
  2340.       ptk_unpostmenu(viewwsid, mapmenuid);
  2341.       ptk_unpostmenu(viewwsid, orimenuid);
  2342.       ptk_redrawallstructs(viewwsid, PFLAG_ALWAYS);
  2343.       break;
  2344.  
  2345.     case 4: /* reset */
  2346.       pset_disp_upd_st(viewwsid, PDEFER_WAIT, PMODE_NIVE); 
  2347.       vpn = ptk_point3(0.0, 0.0, 1.0);
  2348.       vup = ptk_point3(0.0, 1.0, 0.0);
  2349.       viewmap.view_plane = 0.0;
  2350.       viewmap.proj_type = PTYPE_PARAL;
  2351.       maxscenevol = PTKMAX(scenevol.x, scenevol.y);
  2352.       maxscenevol = PTKMAX(maxscenevol, scenevol.z);
  2353.       maxscenevol *= 2.0;
  2354.       viewmap.proj_vp = ptk_limit3(0.5 - scenevol.x / maxscenevol, 
  2355.                              0.5 + scenevol.x / maxscenevol,
  2356.                              0.5 - scenevol.y / maxscenevol, 
  2357.                              0.5 + scenevol.y / maxscenevol,
  2358.                              0.5 - scenevol.z / maxscenevol, 
  2359.                              0.5 + scenevol.z / maxscenevol);
  2360.       vrp = initvrp;
  2361.       viewmap.win = ptk_limit(-scenevol.x / 2.0, scenevol.x / 2.0, 
  2362.                              -scenevol.y / 2.0, scenevol.y / 2.0);
  2363.       viewmap.proj_ref_point = ptk_point3(0.0, 0.0, scenevol.z);
  2364.       viewmap.front_plane = scenevol.z / 2.0;
  2365.       viewmap.back_plane = -scenevol.z / 2.0;
  2366.       clipxy = PIND_NO_CLIP;
  2367.       clipfront = PIND_NO_CLIP;
  2368.       clipback = PIND_NO_CLIP;
  2369.       updatemxvom();
  2370.       updatemxinvvom();
  2371.       updatemxvmm();
  2372.       updatemxviewvolume();
  2373.       updatemxprojviewport();
  2374.       updatemxviewplane();
  2375.       updatemxprp();
  2376.       updatedcwindow();
  2377.       ptk_redrawallstructs(viewwsid, PFLAG_ALWAYS);
  2378.       break;
  2379.  
  2380.     case 5: /* keyboard or rotator input */
  2381.       pset_disp_upd_st(viewwsid, PDEFER_WAIT, PMODE_NIVE); 
  2382.       if (inputmode)
  2383.       {
  2384.         /* change to keyboard mode */
  2385.         ptk_createtextmenuitem(viewmenuid, "rotator", 5, PEDIT_REPLACE, &err);
  2386.         inputmode = FALSE;
  2387.       }
  2388.       else
  2389.       {
  2390.         /* change to rotator input */
  2391.         ptk_createtextmenuitem(viewmenuid, "keyboard", 5, PEDIT_REPLACE, 
  2392.                                &err);
  2393.         inputmode = TRUE;
  2394.       }
  2395.       ptk_redrawallstructs(viewwsid, PFLAG_ALWAYS);
  2396.       break;
  2397.  
  2398.     case 6: /* inquire viewing values */
  2399.       do_inquire();
  2400.       break;
  2401.  
  2402.     case 7: /* refresh */
  2403.       pset_disp_upd_st(viewwsid, PDEFER_WAIT, PMODE_NIVE);
  2404.       predraw_all_structs(viewwsid, PFLAG_ALWAYS);
  2405.       break;
  2406.   }  
  2407. }  /* do_viewmenu */
  2408.  
  2409. /*--------------------------------------------------------------------------*/
  2410.  
  2411. static void do_windowmenu(C(Pint) menuitem, C(ptkswindowoutput *) windoutput)
  2412. PreANSI(Pint menuitem)
  2413. PreANSI(ptkswindowoutput *windoutput)
  2414. {
  2415.   ptkboolean closed;
  2416.   Ppoint initpt, locpos;
  2417.   Plimit echo;
  2418.   Ploc_data locrec;
  2419.   Pint err, initview, viewindex;
  2420.   Pin_status status;
  2421.  
  2422.   if (windoutput->windowarea == PTKEWINDOWICON)
  2423.     closed = TRUE;
  2424.   else
  2425.     closed = FALSE;
  2426.   echo = ptk_limit(0.0, maxdevx, 0.0, maxdevy);
  2427.   switch (menuitem)
  2428.   {
  2429.     case 1: /* open/close */
  2430.       ptk_unpostmenu(viewwsid, windowmenuid);
  2431.       if (closed)
  2432.       {
  2433.         if (windoutput->windowid == dcwindow)
  2434.           dcopen = TRUE;
  2435.         ptk_openwindow(windoutput->windowid);
  2436.       }
  2437.       else
  2438.       {
  2439.         if (windoutput->windowid == dcwindow)
  2440.           dcopen = FALSE;
  2441.         ptk_closewindow(windoutput->windowid);
  2442.       }
  2443.       break;
  2444.  
  2445.     case 2: /* move */
  2446.       {
  2447.         initview = 0;
  2448.         if (closed)
  2449.           ptk_inqiconposition(windoutput->windowid, &initpt, &err);
  2450.         else
  2451.           ptk_inqwindowposition(windoutput->windowid, &initpt, &err);
  2452.         /* Implementation dependent - locator data record */
  2453. #ifdef HP
  2454.         locrec.pets.pet_r1.loc_colr_ind = 1;
  2455. #endif
  2456.         pinit_loc(viewwsid, LOCDEV, initview, &initpt, 1, &echo, &locrec);
  2457.         pset_loc_mode(viewwsid, LOCDEV, POP_REQ, PSWITCH_ECHO);
  2458.         preq_loc(viewwsid, LOCDEV, &status, &viewindex, &locpos);
  2459.         if (status == PIN_STATUS_OK)
  2460.           if (closed)
  2461.             ptk_seticonposition(windoutput->windowid, &locpos);
  2462.           else
  2463.       {
  2464.             pset_disp_upd_st(viewwsid, PDEFER_WAIT, PMODE_NIVE);
  2465.             ptk_setwindowposition(windoutput->windowid, &locpos);
  2466.           }
  2467.       }
  2468.       ptk_unpostmenu(viewwsid, windowmenuid);
  2469.       break;
  2470.  
  2471.     case 3: /* resize */
  2472.       {
  2473.         Pfloat width, height;
  2474.         Ppoint size;
  2475.  
  2476.         initview = 0;
  2477.         if (closed)
  2478.           ptk_inqiconposition(windoutput->windowid, &initpt, &err);
  2479.         else
  2480.           ptk_inqwindowposition(windoutput->windowid, &initpt, &err);
  2481.  
  2482.         /* Implementation dependent code to give
  2483.         ** rubber banding rectangle (locator pet)
  2484.         */
  2485. #ifdef SUN
  2486.         locrec.pets.pet_u5.line_bundle.type = PLINE_SOLID;
  2487.         locrec.pets.pet_u5.line_bundle.width = 1.0;
  2488.         locrec.pets.pet_u5.line_bundle.colr_ind = 1;
  2489.         pinit_loc(viewwsid, LOCDEV, initview, &initpt, -5, &echo, &locrec);
  2490. #endif
  2491. #ifdef HP
  2492.         locrec.pets.pet_r5.line_fill_ctrl_flag = PFLAG_LINE;
  2493.         locrec.pets.pet_r5.attrs.line_attrs.type_asf = PASF_INDIV;
  2494.         locrec.pets.pet_r5.attrs.line_attrs.width_asf = PASF_INDIV;
  2495.         locrec.pets.pet_r5.attrs.line_attrs.colr_ind_asf = PASF_INDIV;
  2496.         locrec.pets.pet_r5.attrs.line_attrs.bundle.type = PLINE_SOLID;
  2497.         locrec.pets.pet_r5.attrs.line_attrs.bundle.width = 1.0;      
  2498.         locrec.pets.pet_r5.attrs.line_attrs.bundle.colr_ind = 1;
  2499.         pinit_loc(viewwsid, LOCDEV, initview, &initpt, 5, &echo, &locrec);
  2500. #endif
  2501. #ifdef PEXSI
  2502.         pinit_loc(viewwsid, LOCDEV, initview, &initpt, 1, &echo, &locrec);
  2503. #endif
  2504.         pset_loc_mode(viewwsid, LOCDEV, POP_REQ, PSWITCH_ECHO);
  2505.         preq_loc(viewwsid, LOCDEV, &status, &viewindex, &locpos);
  2506.         if (status == PIN_STATUS_OK)
  2507.     {
  2508.           width = PTKMAX(initpt.x, locpos.x) - PTKMIN(initpt.x, locpos.x);
  2509.           height = PTKMAX(initpt.y, locpos.y) - PTKMIN(initpt.y, locpos.y);
  2510.           width *= 2.0;
  2511.           height *= 2.0;
  2512.           size = ptk_point(width, height);
  2513.           if (closed)
  2514.             ptk_seticonsize(windoutput->windowid, &size);
  2515.           else
  2516.       {
  2517.             pset_disp_upd_st(viewwsid, PDEFER_WAIT, PMODE_NIVE);
  2518.             ptk_setwindowsize(windoutput->windowid, &size);
  2519.           }
  2520.         }
  2521.         /* Implementation dependent - locator data record */
  2522. #ifdef HP
  2523.         locrec.pets.pet_r1.loc_colr_ind = 1;
  2524. #endif
  2525.         pinit_loc(viewwsid, LOCDEV, initview, &initpt, 1, &echo, &locrec);
  2526.       }
  2527.       ptk_unpostmenu(viewwsid, windowmenuid);      
  2528.       break;
  2529.  
  2530.     case 4: /* front */
  2531.       pset_disp_upd_st(viewwsid, PDEFER_WAIT, PMODE_NIVE);
  2532.       ptk_unpostmenu(viewwsid, windowmenuid);
  2533.       ptk_frontwindow(windoutput->windowid);
  2534.       break;
  2535.  
  2536.     case 5: /* back */
  2537.       pset_disp_upd_st(viewwsid, PDEFER_WAIT, PMODE_NIVE);
  2538.       ptk_unpostmenu(viewwsid, windowmenuid);
  2539.       ptk_backwindow(windoutput->windowid);
  2540.       break;
  2541.  
  2542.     case 6: /* camera or scroll */
  2543.       ptk_unpostmenu(viewwsid, windowmenuid);
  2544.       if (windoutput->windowid == terminalwindow)
  2545.         do_scrollterminal();
  2546.       else
  2547.         camerainterface(windoutput->windowid);
  2548.       break;
  2549.   }  
  2550.   ptk_redrawallstructs(viewwsid, PFLAG_ALWAYS);
  2551. }  /* do_windowmenu */
  2552.  
  2553. /*--------------------------------------------------------------------------*/
  2554.  
  2555. static void viewmainloop()
  2556. {
  2557.   ptkboolean viewquit;
  2558.   Pint wsid, devnum, initview, viewindex;
  2559.   Pin_class class;
  2560.   Ppoint initpt, locpos;
  2561.   ptksgeneralinput geninput;
  2562.   ptksmenuoutput menuoutput;
  2563.   ptkswindowoutput windowoutput;
  2564.   Ploc_data locrec;
  2565.   Plimit echo;
  2566.  
  2567.   viewquit = FALSE;
  2568.   pset_loc_mode(viewwsid, LOCDEV, POP_REQ, PSWITCH_ECHO);
  2569.   initview = 0;
  2570.   initpt = ptk_point(0.5, 0.5);
  2571.   echo = ptk_limit(0.0, maxdevx, 0.0, maxdevy);
  2572.   /* Implementation dependent - locator data record */
  2573. #ifdef HP
  2574.   locrec.pets.pet_r1.loc_colr_ind = 1;
  2575. #endif
  2576.   pflush_events(viewwsid, PIN_LOC, LOCDEV);
  2577.   pinit_loc(viewwsid, LOCDEV, initview, &initpt, 1, &echo, &locrec);
  2578.   pset_loc_mode(viewwsid, LOCDEV, POP_EVENT, PSWITCH_ECHO);
  2579.   ptk_redrawallstructs(viewwsid, PFLAG_ALWAYS);
  2580.   do
  2581.   {
  2582.     pset_disp_upd_st(viewwsid, PDEFER_WAIT, PMODE_UQUM); 
  2583.     pawait_event(0.0, &wsid, &class, &devnum);
  2584.     if ((class == PIN_LOC) && (wsid == viewwsid))
  2585.     {
  2586.       pget_loc(&viewindex, &locpos);
  2587.       geninput.inputclass = PIN_LOC;
  2588.       geninput.ptkugeninput.locpoint = locpos;
  2589.       if (ptk_scanmenus(viewwsid, &geninput, &menuoutput))
  2590.       {
  2591.         pset_loc_mode(viewwsid, LOCDEV, POP_REQ, PSWITCH_ECHO);
  2592.         if (menuoutput.menuid == orimenuid)
  2593.     {
  2594.           do_orimenu(menuoutput.itemnum);
  2595.           ptk_redrawallstructs(viewwsid, PFLAG_ALWAYS);
  2596.     }
  2597.         else
  2598.         if (menuoutput.menuid == mapmenuid)
  2599.     {
  2600.           do_mapmenu(menuoutput.itemnum);
  2601.           ptk_redrawallstructs(viewwsid, PFLAG_ALWAYS);
  2602.     }
  2603.         else
  2604.         if (menuoutput.menuid == clipmenuid)
  2605.     {
  2606.           do_clipmenu(menuoutput.itemnum);
  2607.           ptk_redrawallstructs(viewwsid, PFLAG_ALWAYS);
  2608.     }
  2609.         else
  2610.         if (menuoutput.menuid == viewmenuid)
  2611.     {
  2612.           if (menuoutput.itemnum == 8)
  2613.             viewquit = TRUE;
  2614.           else
  2615.             do_viewmenu(menuoutput.itemnum, &locpos);
  2616.     }
  2617.         else
  2618.         if (menuoutput.menuid == windowmenuid)
  2619.     {
  2620.           do_windowmenu(menuoutput.itemnum, &windowoutput);
  2621.           curmenu = 0;
  2622.         }
  2623.         pset_loc_mode(viewwsid, LOCDEV, POP_EVENT, PSWITCH_ECHO);
  2624.       }
  2625.       else
  2626.       if (ptk_scanwindows(viewwsid, &geninput, &windowoutput))
  2627.       {
  2628.         Pint err;
  2629.  
  2630.         ptk_unpostallmenu(viewwsid);
  2631.         if (windowoutput.windowarea == PTKEWINDOWICON)
  2632.           ptk_createtextmenuitem(windowmenuid, "open", 1, PEDIT_REPLACE, &err);
  2633.         else
  2634.           ptk_createtextmenuitem(windowmenuid, "close", 1, PEDIT_REPLACE, &err);
  2635.         if (windowoutput.windowid == dcwindow)
  2636.           ptk_delmenuitem(windowmenuid, 6);
  2637.         else
  2638.         if (windowoutput.windowid == terminalwindow)
  2639.     {
  2640.           ptkewindowstate state;
  2641.  
  2642.           ptk_inqwindowstate(terminalwindow, &state, &err);
  2643.           if (state == PTKEWINDOWOPEN)
  2644.             ptk_createtextmenuitem(windowmenuid, "scroll", 6, PEDIT_REPLACE, 
  2645.                                  &err);
  2646.           else
  2647.             ptk_delmenuitem(windowmenuid, 6);
  2648.         }
  2649.         else
  2650.           ptk_createtextmenuitem(windowmenuid, "camera", 6, PEDIT_REPLACE, 
  2651.                                  &err);
  2652.         if ((curmenu != windowmenuid) || (curwindow != windowoutput.windowid))
  2653.     {
  2654.           ptk_setmenuposition(windowmenuid, &locpos);
  2655.           ptk_postmenu(viewwsid, windowmenuid);
  2656.           curwindow = windowoutput.windowid;
  2657.           curmenu = windowmenuid;
  2658.         }
  2659.         else
  2660.     {
  2661.           curwindow = 0;
  2662.           curmenu = 0;
  2663.         }
  2664.         ptk_redrawallstructs(viewwsid, PFLAG_ALWAYS);
  2665.       }
  2666.       else
  2667.       {
  2668.         curwindow = 0;
  2669.         ptk_unpostallmenu(viewwsid);
  2670.         if (curmenu != viewmenuid)
  2671.     {
  2672.           ptk_setmenuposition(viewmenuid, &locpos);
  2673.           ptk_postmenu(viewwsid, viewmenuid);
  2674.           curmenu = viewmenuid;
  2675.         }
  2676.         else
  2677.           curmenu = 0;
  2678.         ptk_redrawallstructs(viewwsid, PFLAG_ALWAYS);
  2679.       }
  2680.     }
  2681.   } while (!viewquit);
  2682.   pflush_events(viewwsid, PIN_LOC, LOCDEV);
  2683. }  /* viewmainloop */
  2684.  
  2685. /*--------------------------------------------------------------------------*/
  2686.  
  2687. /*function:external*/
  2688. extern void ptk_vieweditor(C(Pint) wsid, C(Pint_list *) stids, 
  2689.                            C(Pview_rep3 *) rep)
  2690. PreANSI(Pint wsid)
  2691. PreANSI(Pint_list *stids)
  2692. PreANSI(Pview_rep3 *rep)
  2693. /*
  2694. ** \parambegin
  2695. ** \param{Pint}{wsid}{workstation identifier}{IN}
  2696. ** \param{Pint\_list *}{stids}{list of structure identifiers}{IN}
  2697. ** \param{Pview\_rep3 *}{rep}{view representation}{OUT}
  2698. ** \paramend
  2699. ** \blurb{This function starts the interactive PHIGS view editor, on
  2700. **  workstation \pardesc{ws}.
  2701. ** This function requires hashtables
  2702. ** "structureid", "label", "name", "viewindex", "topologyid", "menuid",
  2703. ** "windowid".}
  2704. */
  2705. {
  2706.   Ppoint pos, size;
  2707.   Pint lenstr, err, stcom, totsize, i;
  2708.   Pint_list pmenus, pwindows;
  2709.   Pposted_struct_list structs;
  2710.   Pdefer_mode defmode;
  2711.   Pmod_mode modmode;
  2712.   Pdisp_surf_empty dspsurf;
  2713.   Pvisual_st visualrep;
  2714.   Pcolr_rep backrep;
  2715.  
  2716.   viewscene =  ptk_stringtoint("structureid", "ptk$viewscene");
  2717.   if (!do_scene(stids))
  2718.   {
  2719.     fprintf(stderr, "View editor: the given scene cannot be viewed.\n");
  2720.     return;
  2721.   }
  2722.  
  2723.   /* inquire and set display update state */
  2724.   pinq_disp_upd_st(wsid, &err, &defmode, &modmode, &dspsurf, &visualrep);
  2725.   pset_disp_upd_st(wsid, PDEFER_WAIT, PMODE_NIVE);
  2726.  
  2727.   /* inquire and set background colour */
  2728.   pinq_colr_rep(wsid, 0, PINQ_SET, &err, &backrep);
  2729.   ptk_setbackgroundcolourind(wsid, backgroundcolourind);
  2730.  
  2731.   /* inquire all posted menus and windows */
  2732.   ptk_inqpostedmenus(wsid, 0, &pmenus, &totsize, &err);
  2733.   pmenus.ints = (Pint *)calloc(totsize, sizeof(Pint));
  2734.   ptk_inqpostedmenus(wsid, totsize, &pmenus, &totsize, &err);
  2735.   pmenus.num_ints = totsize;
  2736.   ptk_inqpostedwindows(wsid, 0, &pwindows, &totsize, &err);
  2737.   pwindows.ints = (Pint *)calloc(totsize, sizeof(Pint));
  2738.   ptk_inqpostedwindows(wsid, totsize, &pwindows, &totsize, &err);
  2739.   pwindows.num_ints = totsize;
  2740.   /* clear menus and windows */
  2741.   for (i = 0; i < pmenus.num_ints; i++)
  2742.     ptk_unpostmenu(wsid, pmenus.ints[i]);
  2743.   for (i = 0; i < pwindows.num_ints; i++)
  2744.     ptk_unpostwindow(wsid, pwindows.ints[i]);
  2745.  
  2746.   /* inquire all other posted structure */
  2747.   pinq_posted_structs(wsid, 0, 0, &err, &structs, &totsize);
  2748.   structs.postings = (Pposted_struct *)calloc(totsize, sizeof(Pposted_struct));
  2749.   pinq_posted_structs(wsid, totsize, 0, &err, &structs, &totsize);
  2750.   structs.num_postings = totsize;
  2751.   /* clear all posted structures */
  2752.   punpost_all_structs(wsid);
  2753.  
  2754.   /* clear workstation */
  2755.  
  2756.   viewwsid = wsid;
  2757.   ptk_inqmaxdevicecoords(wsid, &maxdevx, &maxdevy);
  2758.   echoarea = ptk_limit(0.0, maxdevx * 0.5, 0.0, maxdevy * 0.05);
  2759.   /* set up windows */
  2760.   pos = ptk_point(0.25, 0.25);
  2761.   size = ptk_point(0.45, 0.45);     
  2762.  
  2763.   wcwindow = ptk_stringtoint("windowid", "ptk$wcwindow");
  2764.   vrcwindow = ptk_stringtoint("windowid", "ptk$vrcwindow");
  2765.   npcwindow = ptk_stringtoint("windowid", "ptk$npcwindow");
  2766.   dcwindow = ptk_stringtoint("windowid", "ptk$dcwindow");
  2767.   terminalwindow = ptk_stringtoint("windowid", "ptk$terminalwindow");
  2768.   viewscene =  ptk_stringtoint("structureid", "ptk$viewscene");
  2769.   wcscene =  ptk_stringtoint("structureid", "ptk$viewwcscene");
  2770.   vrcscene =  ptk_stringtoint("structureid", "ptk$viewvrcscene");
  2771.   npcscene =  ptk_stringtoint("structureid", "ptk$viewnpcscene");
  2772.   dcscene =  ptk_stringtoint("structureid", "ptk$viewdcscene");
  2773.   ptk_createwindow(wsid, wcwindow, &size, &pos, "world coords");
  2774.   ptk_setwindowattrs(wcwindow, windowtextfont, bannertextcolourind,
  2775.                      bannercolourind, windowcolourind,
  2776.                      bannercolourind, tlcolourind, brcolourind);
  2777.   pos = ptk_point(0.25, 0.75);
  2778.   ptk_createwindow(wsid, vrcwindow, &size, &pos, "view reference coords");
  2779.   ptk_setwindowattrs(vrcwindow, windowtextfont, bannertextcolourind,
  2780.                      bannercolourind, windowcolourind,
  2781.                      bannercolourind, tlcolourind, brcolourind);
  2782.   pos = ptk_point(0.75, 0.75);
  2783.   ptk_createwindow(wsid, npcwindow, &size, &pos, 
  2784.                    "normalised projection coords");
  2785.   ptk_setwindowattrs(npcwindow, windowtextfont, bannertextcolourind,
  2786.                      bannercolourind, windowcolourind,
  2787.                      bannercolourind, tlcolourind, brcolourind);
  2788.   pos = ptk_point(0.75, 0.25);
  2789.   ptk_createwindow(wsid, dcwindow, &size, &pos, "device coords");
  2790.   ptk_setwindowattrs(dcwindow, windowtextfont, bannertextcolourind,
  2791.                      bannercolourind, windowcolourind,
  2792.                      bannercolourind, tlcolourind, brcolourind);
  2793.   pos = ptk_point(0.5, 0.5);
  2794.   ptk_createwindow(wsid, terminalwindow, &size, &pos, "terminal");
  2795.   ptk_setwindowattrs(terminalwindow, windowtextfont, bannertextcolourind,
  2796.                      bannercolourind, windowcolourind,
  2797.                      bannercolourind, tlcolourind, brcolourind);
  2798.   ptk_setwindowtype(terminalwindow, PTKETERMINALWINDOW);
  2799.   ptk_postwindow(wcwindow);
  2800.   ptk_postwindow(vrcwindow); 
  2801.   ptk_postwindow(npcwindow);
  2802.   ptk_postwindow(dcwindow);
  2803.   ptk_postwindow(terminalwindow);
  2804.   ptk_closewindow(terminalwindow);
  2805.  
  2806.   /* set up menus */
  2807.   makemenus();
  2808.   
  2809.   makeviewstructs();
  2810.  
  2811.   initialiseeditor();
  2812.   
  2813.   updatemxvom();
  2814.   updatemxinvvom();
  2815.   updatemxvmm();
  2816.   updatemxviewvolume();
  2817.   updatemxprojviewport();
  2818.   updatemxprp();
  2819.   updatemxviewplane();
  2820.  
  2821.   updatewindows(); 
  2822.   ptk_redrawallstructs(viewwsid, PFLAG_ALWAYS);
  2823.  
  2824.   /* interaction loop */
  2825.   viewmainloop();
  2826.  
  2827.   pset_disp_upd_st(wsid, PDEFER_WAIT, PMODE_NIVE);
  2828.  
  2829.   /* tidy up before exit */
  2830.   /* delete windows */
  2831.   ptk_delwindow(wcwindow);
  2832.   ptk_delwindow(vrcwindow);
  2833.   ptk_delwindow(npcwindow);
  2834.   ptk_delwindow(dcwindow);
  2835.   ptk_delwindow(terminalwindow);
  2836.  
  2837.   ptk_delstring("windowid", "ptk$wcwindow");
  2838.   ptk_delstring("windowid", "ptk$vrcwindow");
  2839.   ptk_delstring("windowid", "ptk$npcwindow");
  2840.   ptk_delstring("windowid", "ptk$dcwindow");
  2841.   ptk_delstring("windowid", "ptk$terminalwindow");
  2842.  
  2843.   /* reset view editor variables */
  2844.   clipxy = PIND_NO_CLIP;
  2845.   clipfront = PIND_NO_CLIP;
  2846.   clipback = PIND_NO_CLIP;
  2847.   curmenu = 0;
  2848.   curwindow = 0;
  2849.   inputmode = TRUE;
  2850.   dcopen = TRUE;
  2851.  
  2852.   /* delete menus */
  2853.   ptk_delmenu(viewmenuid);
  2854.   ptk_delmenu(orimenuid);
  2855.   ptk_delmenu(mapmenuid);
  2856.   ptk_delmenu(windowmenuid); 
  2857.   ptk_delmenu(clipmenuid);
  2858.  
  2859.   ptk_delstring("menuid", "ptk$viewmenu"); 
  2860.   ptk_delstring("menuid", "ptk$orientationmenu"); 
  2861.   ptk_delstring("menuid", "ptk$mappingmenu"); 
  2862.   ptk_delstring("menuid", "ptk$windowmenu"); 
  2863.   ptk_delstring("menuid", "ptk$clippingmenu"); 
  2864.  
  2865.   /* delete rotators */
  2866.   ptk_delmenu(rot3d1);
  2867.   ptk_delmenu(rot3d2);
  2868.   ptk_delmenu(rot2d1);
  2869.   ptk_delmenu(rot2d2);
  2870.   ptk_delmenu(rot1d);
  2871.  
  2872.   ptk_delstring("menuid", "ptk$rotator3d1"); 
  2873.   ptk_delstring("menuid", "ptk$rotator3d2"); 
  2874.   ptk_delstring("menuid", "ptk$rotator2d1"); 
  2875.   ptk_delstring("menuid", "ptk$rotator2d2"); 
  2876.   ptk_delstring("menuid", "ptk$rotator1d"); 
  2877.  
  2878.   /* delete view editor structures */
  2879.   pdel_struct(wcaxes); 
  2880.   ptk_delstring("structureid", "ptk$viewwcaxes");
  2881.   pdel_struct(vrcaxes);
  2882.   ptk_delstring("structureid", "ptk$viewvrcaxes");
  2883.   pdel_struct(npccube);
  2884.   ptk_delstring("structureid", "ptk$viewnpccube");
  2885.   pdel_struct(projviewport);
  2886.   ptk_delstring("structureid", "ptk$viewprojviewport");
  2887.   pdel_struct(viewvolume);
  2888.   ptk_delstring("structureid", "ptk$viewviewvolume");
  2889.   pdel_struct(prpmarker);
  2890.   ptk_delstring("structureid", "ptk$viewprpmarker");
  2891.   pdel_struct(viewplane);
  2892.   ptk_delstring("structureid", "ptk$viewviewplane");
  2893.  
  2894.   pdel_struct(viewscene);
  2895.   ptk_delstring("structureid", "ptk$viewscene");
  2896.   pdel_struct(wcscene);
  2897.   ptk_delstring("structureid", "ptk$viewwcscene");
  2898.   pdel_struct(vrcscene);
  2899.   ptk_delstring("structureid", "ptk$viewvrcscene");
  2900.   pdel_struct(npcscene);
  2901.   ptk_delstring("structureid", "ptk$viewnpcscene");
  2902.   pdel_struct(dcscene); 
  2903.   ptk_delstring("structureid", "ptk$viewdcscene");
  2904.  
  2905.   ptk_delstring("label", "view$mx_inv_vom");
  2906.   ptk_delstring("label", "view$mx_view_volume");
  2907.   ptk_delstring("label", "view$mx_prp");
  2908.   ptk_delstring("label", "view$mx_proj_viewport");
  2909.   ptk_delstring("label", "view$mx_vom");
  2910.   ptk_delstring("label", "view$mx_vmm");
  2911.   ptk_delstring("label", "view$mx_view_plane");
  2912.  
  2913.   /* return view representation */
  2914.   memcpy(rep->ori_matrix, vommat, sizeof(Pmatrix3)); 
  2915.   memcpy(rep->map_matrix, vmmmat, sizeof(Pmatrix3)); 
  2916.   rep->xy_clip = clipxy;
  2917.   rep->front_clip = clipfront;
  2918.   rep->back_clip = clipback;
  2919.   rep->clip_limit = viewmap.proj_vp;
  2920.  
  2921.   /* repost all menus, windows and other structs */
  2922.   for (i = 0; i < structs.num_postings; i++)
  2923.     ppost_struct(wsid, structs.postings[i].id, structs.postings[i].disp_pri);
  2924.   for (i = 0; i < pwindows.num_ints; i++)
  2925.     ptk_postwindow(pwindows.ints[i]);
  2926.   for (i = 0; i < pmenus.num_ints; i++)
  2927.     ptk_postmenu(wsid, pmenus.ints[i]);
  2928.   free(structs.postings);
  2929.   free(pmenus.ints);
  2930.   free(pwindows.ints);
  2931.  
  2932.   /* background colour */
  2933.   pset_colr_rep(wsid, 0, &backrep);
  2934.  
  2935.   ptk_redrawallstructs(wsid, PFLAG_ALWAYS);
  2936.  
  2937.   /* restore display update state */
  2938.   pset_disp_upd_st(wsid, defmode, modmode); 
  2939. }  /* ptk_vieweditor */
  2940.  
  2941. /*--------------------------------------------------------------------------*/
  2942.  
  2943. /*function:external*/
  2944. extern void ptk_setvieweditorattrs(C(Pint) menufont, C(Pint) windowfont,
  2945.               C(Pint) menucol, C(Pint) menutextcol, 
  2946.               C(Pint) windowcol, C(Pint) bannercol, C(Pint) bannertextcol, 
  2947.        C(Pint) tlcol, C(Pint) brcol, C(Pint) arrowcol, C(Pint) arrowedgecol)
  2948. PreANSI(Pint menufont)
  2949. PreANSI(Pint windowfont)
  2950. PreANSI(Pint menucol)
  2951. PreANSI(Pint menutextcol)
  2952. PreANSI(Pint windowcol)
  2953. PreANSI(Pint bannercol)
  2954. PreANSI(Pint bannertextcol)
  2955. PreANSI(Pint tlcol)
  2956. PreANSI(Pint brcol)
  2957. PreANSI(Pint arrowcol)
  2958. PreANSI(Pint arrowedgecol)
  2959. /*
  2960. ** \parambegin
  2961. ** \param{Pint}{menufont}{menu text font}{IN}
  2962. ** \param{Pint}{windowfont}{window text font}{IN}
  2963. ** \param{Pint}{menucol}{menu colour index}{IN}
  2964. ** \param{Pint}{menutextcol}{menu text colour index}{IN}
  2965. ** \param{Pint}{windowcol}{window interior colour index}{IN}
  2966. ** \param{Pint}{bannercol}{window banner colour index}{IN}
  2967. ** \param{Pint}{bannertextcol}{window banner text colour index}{IN}
  2968. ** \param{Pint}{tlcol}{top-left colour index}{IN}
  2969. ** \param{Pint}{brcol}{bottom-right colour index}{IN}
  2970. ** \param{Pint}{arrowcol}{arrow colour index}{IN}
  2971. ** \param{Pint}{arrowedgecol}{arrow edge colour index}{IN}
  2972. ** \paramend
  2973. ** \blurb{This function enables the application to
  2974. ** set the text font and colour attribute values for the menus and windows
  2975. **  used in the PHIGS view editor.}
  2976. */
  2977. {
  2978.   menutextfont = menufont;
  2979.   windowtextfont = windowfont;
  2980.   menucolourind = menucol;
  2981.   windowcolourind = windowcol;
  2982.   menutextcolourind = menutextcol;
  2983.   bannercolourind = bannercol;
  2984.   bannertextcolourind = bannertextcol;
  2985.   tlcolourind = tlcol;
  2986.   brcolourind = brcol;
  2987.   arrowcolourind = arrowcol;
  2988.   arrowedgecolourind = arrowedgecol;
  2989. } /* ptk_setvieweditorattrs */
  2990.  
  2991. /*--------------------------------------------------------------------------*/
  2992.  
  2993. /*function:external*/
  2994. extern void ptk_inqvieweditorattrs(C(Pint *) menufont, C(Pint *) windowfont, 
  2995.            C(Pint *) menucol, C(Pint *) menutextcol, C(Pint *) windowcol, 
  2996.            C(Pint *) bannercol, C(Pint *) bannertextcol, C(Pint *) tlcol, 
  2997.            C(Pint *) brcol, C(Pint *) arrowcol, C(Pint *) arrowedgecol)
  2998. PreANSI(Pint *menufont)
  2999. PreANSI(Pint *windowfont)
  3000. PreANSI(Pint *menucol)
  3001. PreANSI(Pint *menutextcol)
  3002. PreANSI(Pint *windowcol)
  3003. PreANSI(Pint *bannercol)
  3004. PreANSI(Pint *bannertextcol)
  3005. PreANSI(Pint *tlcol)
  3006. PreANSI(Pint *brcol)
  3007. PreANSI(Pint *arrowcol)
  3008. PreANSI(Pint *arrowedgecol)
  3009. /*
  3010. ** \parambegin
  3011. ** \param{Pint *}{menufont}{menu text font}{IN}
  3012. ** \param{Pint *}{windowfont}{window text font}{IN}
  3013. ** \param{Pint *}{menucol}{menu colour index}{IN}
  3014. ** \param{Pint *}{menutextcol}{menu text colour index}{IN}
  3015. ** \param{Pint *}{windowcol}{window interior colour index}{IN}
  3016. ** \param{Pint *}{bannercol}{window banner colour index}{IN}
  3017. ** \param{Pint *}{bannertextcol}{window banner text colour index}{IN}
  3018. ** \param{Pint *}{tlcol}{top-left colour index}{IN}
  3019. ** \param{Pint *}{brcol}{bottom-right colour index}{IN}
  3020. ** \param{Pint *}{arrowcol}{arrow colour index}{IN}
  3021. ** \param{Pint *}{arrowedgecol}{arrow edge colour index}{IN}
  3022. ** \paramend
  3023. ** \blurb{This function may be used to obtain the text font and 
  3024. ** colour attribute values of menus and windows used in the PHIGS view
  3025. ** editor.}
  3026. */
  3027. {
  3028.   *menufont = menutextfont;
  3029.   *windowfont = windowtextfont;
  3030.   *menucol = menucolourind;
  3031.   *windowcol = windowcolourind;
  3032.   *menutextcol = menutextcolourind;
  3033.   *bannercol = bannercolourind;
  3034.   *bannertextcol = bannertextcolourind;
  3035.   *tlcol = tlcolourind;
  3036.   *brcol = brcolourind;
  3037.   *arrowcol = arrowcolourind;
  3038.   *arrowedgecol = arrowedgecolourind;
  3039. } /* ptk_inqvieweditorattrs */
  3040.  
  3041. /*--------------------------------------------------------------------------*/
  3042.  
  3043. /* end of view.c */
  3044.